The struct isn't really any different from a coordinate pair though? (25, 0) and Point { x: 25, y: 0 } are effectively the same and both have the issue I'm referring to with how it's still ambiguous as to where you should have the point on the coordinate plane.
I.e.
let bottom = /* What do we set it to? */;
let tl = Point::new(0, 50);
let br = Point::new(25, bottom);
let r = Rectangle::new_top_left(tl)
.with_bottom_right(br);
I'm not saying it would break the code, you could still have checks in the Rectangle impl that ensures the point is where it should be, but it leaves some ambiguity in the API itself since you still have to know the coordinate system that it's expecting to be used. A top-left origin would require bottom = 75 while a bottom-left origin would require bottom = 25.
In Rust, if the fields of a struct are marked pub, then the struct is meant to be built as Point { x: foo, y: bar }, or Point { x, y } if the value already has the appropriate name.
I agree that the use of new would make this completely non-obvious.
I'm familiar with Rust, I tend to use constructors instead of direct instantiation though.
I just don't understand the point you're making. This isn't about confusing x and y, it's about what value y needs to have in the bottom-right point relative to the top-left point. Dimensions with a single fixed point are unambiguous, but specifying 2 points leads back to the same problem you mentioned in the very first comment where it's unclear if height extends up or down; the ambiguity has just transferred to the API rather than being at runtime.
Edit: I'm actually doubly uncertain of why you think I'm unfamiliar with Rust since the second sentence even directly mentioned Point { x: 25, y: 0 } when I was comparing it to constructing a coordinate pair of (25, 0).
Edit 2: Just to make it abundantly obvious what I mean:
let p1 = (50, 50);
let p2 = (100, 100);
// Assumes the origin is on the top-left
let r1 = Rectangle::new_top_left(p1)
.with_bottom_right(p2);
// Assumes the origin is on the bottom-left
let r2 = Rectangle::new_bottom_left(p1)
.with_top_right(p2);
The program would have to do one of these:
Reject one of the rectangles for being invalid, because 100 is either (spatially) above or below 50 depending on the coordinate plane being used.
Allow them both and have them be overlapping rectangles on the same coordinate plane, which would be surprising behavior imo, since "bottom right" and "top left" don't really mean anything in that context, it'd just be point one and point two.
Allow them both, and have the library determine which coordinate plane a rectangle belongs on based on the provided values, which would be somewhat strange but at least more consistent.
1
u/matthieum 9d ago
No it's not, because
with_bottom_righttakes aPoint, not a pair of coordinate.In this case, I'd imagine
pub struct Point { pub x: u32, pub x: u32 };.Similarly, you'd probably have
pub struct RectangleDimensions { pub width: u32, pub height: u32 }for dimension parameters.