Constraining an object within a concave shape while dragging is a rather difficult problem. You can easily construct examples that have no single "closest valid location"
In the general case I think this would probably require some kind of iterative solver.
If all you care about is the destination, you could use several calls to rect.overlaps[] to see if the player object overlaps any obstacles and "snap back" as demonstrated in the examples.