Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Less painful range construction #25

Closed
jeff-davis opened this issue Jan 2, 2014 · 7 comments
Closed

Less painful range construction #25

jeff-davis opened this issue Jan 2, 2014 · 7 comments

Comments

@jeff-davis
Copy link
Contributor

https://gist.github.com/sfackler/4c4e93f896e881fae811

I like that solution there. It is reasonably readable, does compile-time checking, and matches the postgres constructors.

However, it was also suggested on IRC to use something more like:

range!('[' a, b ')')

which is also acceptable to me.

@sfackler
Copy link
Owner

sfackler commented Jan 2, 2014

I kind of like the range!('[' a, b ')') syntax. Would e.g. range!('(' , b ')') be the best syntax for a half-open range?

@jeff-davis
Copy link
Contributor Author

That's a good point: it does seem to extend a little better to unbounded ranges.

Another thought I had is to use textual tokens like II, EI, IE, EE. That is a little awkward to read though and doesn't seem to work naturally for unbounded ranges.

@jeff-davis
Copy link
Contributor Author

I tried implementing it that way, and I ran into a problem. The ranges with no upper bound work fine, but the ranges with no lower bound won't compile and I don't understand why.

macro_rules! range(
   ('(' $low:expr, $high:expr ')') => ("(A,B)");
   ('(' $low:expr, $high:expr ']') => ("(A,B]");
   ('[' $low:expr, $high:expr ')') => ("[A,B)");
   ('[' $low:expr, $high:expr ']') => ("[A,B]");
   ('('          , $high:expr ')') => ("(-inf,B)");
   ('('          , $high:expr ']') => ("(-inf,B]");
   ('(' $low:expr,            ')') => ("(A,inf)");
   ('[' $low:expr,            ')') => ("[A,inf)");
   ($low: expr, $high:expr) => (
      range!('[' $low, $high ')')
   );
)

println!("{}",    range!('('  , 2 ')')   ); // error
println!("{}",    range!('(' 1,   ')')   ); // works fine

@sfackler
Copy link
Owner

sfackler commented Jan 2, 2014

It tries to parse an expression first, fails and doesn't try the next option. Moving the no-lower-bound cases to the top appear to fix it.

@jeff-davis
Copy link
Contributor Author

Yes, thank you, I had just realized that and was about to update my comment.

+1 to this approach

We'll also need a basic constructor for an empty range and a range unbounded on both sides.

@sfackler
Copy link
Owner

sfackler commented Jan 2, 2014

There's already Range::empty() to construct the empty range, but we might as well add range!(empty) and range!('(',')') for completeness.

@sfackler
Copy link
Owner

sfackler commented Jan 2, 2014

I've added a macro to types/range.rs. You'll have to copy/paste it into your source file for now until rust-lang/rust#11151 is finished up.

pimeys pushed a commit to grafbase/rust-postgres that referenced this issue Nov 27, 2023
This is useful / needed to build a Rust client for the Pageserver's
GetPage@LSN API, which uses CopyBoth mode.
petrosagg added a commit to petrosagg/rust-postgres that referenced this issue Aug 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants