-
Notifications
You must be signed in to change notification settings - Fork 24
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
Make overlapping/overlaps accept ranges by-value instead of by-reference #70
Conversation
On mobile, so this will be brief. I'm afraid I don't understand from your description the limitation you've run into. Could you please provide example code for what you'd attempt with the current interface that doesn't work? (Super rough is fine; I'm just trying to understand which bit doesn't fit.) |
Sure, here's something rather simple from what I was doing: struct Addrs {
ipv4: RangeInclusiveSet<u32>,
// ...
}
fn range_v4(net: Ipv4Net) -> RangeInclusive<u32> {
// ...
}
fn map_v4(r: &RangeInclusive<u32>) -> RangeInclusive<Ipv4Addr> {
// ...
}
fn overlapping_v4(&self, net: Ipv4Net) -> impl '_ + Iterator<Item = RangeInclusive<Ipv4Addr>> {
self.ipv4.overlapping(range_v4(net)).map(map_v4)
} Here, I'm using Since the range is being created from another type (in this case, Basically, any iterator adapter that would want to create its own range instead of having one passed from the caller would have this problem. Since you're creating the range inside the method, you can't actually create an |
Could you store the range you generated in the method inside a wrapping struct which you could then impl Iterator on to ensure the range used would always live as long as the iterator adapter? That aside, I deliberated on using references or owned values quite a bit in DiscreteRangeMap but since I can only imagine people using Copy values as you said I went with owned values for slightly nicer ergonomics. |
So this would be a possible solution except that it would mean that instead of returning something along the lines of Which… excusing the fact that this isn't really possible in today's Rust, is a really awkward way to justify not wanting to clone something. Elaborating a bit more on how this would work, your method would return a struct which contains the generated range, and then references to that struct could be converted into a different struct which is iterable, and that conversion would be what calls the |
I'm going to close this since the master branch has been force-pushed since this change, and because it's been left in limbo for over a year with other changes being merged similar to it in the meantime. Feel free to implement it yourself. |
@clarfonthey Sorry about leaving this in limbo; I dropped the ball here. Speaking more broadly, I have very little free time these days so I've been taking a super-conservative approach to maintenance: basically just bug fixes for now. I should probably declare this in the readme. Further down the line I expect life circumstances to allow a bit more time. Then I'll certainly take this into account, and other breaking changes that might be worthwhile to take advantage of cursors, learnings from other crates, etc. |
Oh, life circumstances are extremely understandable; I've got a lot of those myself. I mostly just have been closing old PRs so I can sort of keep track in my open PRs tab. |
Breaking change, but I find this kind of change necessary to interface properly with this API.
Main reasons:
Copy
anyway.Essentially, if you have an iterator method which uses
overlapping
internally, it will only work properly if you pass in a reference to a range directly from the top level; anything else will be insufficient, unless you want to useBox::leak
, which is quite wasteful.