-
Notifications
You must be signed in to change notification settings - Fork 17
self_cell rework #7
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
Conversation
Ported all tests and added a bunch of new ones
Thanks! I tried using the new branch for Fluent work in projectfluent/fluent-rs#221 I really like the changes and the API looks very nice! Here are several items of feedback:
And one blocker:
Even if the I'm not sure how to resolve the blocker, and I recognize that my use case scenario is esoteric, but it definitely is a blocker :( Let me know if the feedback is helpful and if there's something else I can do to help brainstorm that! |
Thanks for the great feedback. I'm working on the various points, a questions I have:
How could I do that? A simple |
Regarding the blocker, one I idea: Owner: Then use the regular |
This also adds support for visibility specifiers
580545c
to
1880cbe
Compare
I tried a couple approaches, and while I found functioning ones, I found none working on stable. Again the no new identifier problem. https://doc.rust-lang.org/std/macro.concat_idents.html would open up a lot of doors. |
This has been addressed with 1880cbe |
@zbraniecki friendly ping. I'd like to resolve your blocker with you before merging this. |
Hi, sorry! Will look into this tomorrow! |
Could you use the whole path when invoking and not import?
Wouldn't
Unfortunately, I can't implement From or Into for
Similar problem for So, I'm still stuck with how to wrangle errors through fallible lazy constructor. I also realized that getting rid of |
Also propagates $Vis to member functions.
Unfortunately that's not enough, https://github.com/Voultapher/once_self_cell/pull/7/files#diff-b1a35a68f14e696205874893c07fd24fdb88882b47c23cc0e0c80a30c7d53759R186 I'm already using the whole path for the type definition. But TIL there is a way to call the trait function without importing it https://stackoverflow.com/questions/25273816/why-do-i-need-to-import-a-trait-to-use-the-methods-it-defines-for-a-type Just pushed a fix, that also includes some visibility fixes. |
Let me see if I can figure out a solution to your blocker. I'll try to build a small POC. |
@zbraniecki here is a POC, it's not ideal because you have to clone the errors, but maybe that isn't a big problem for you. use self_cell::self_cell;
#[derive(Debug, Eq, PartialEq)]
struct Resource<'a>(pub Vec<&'a str>);
fn parse_runtime<'a>(source: &'a String) -> Result<Resource<'a>, (Resource<'a>, Vec<ParseError>)> {
if source.contains("bad") {
Err((Resource(vec![]), vec![ParseError::Dummy]))
} else {
Ok(Resource(
source.split(' ').filter(|word| word.len() > 1).collect(),
))
}
}
#[derive(Clone, Debug)]
enum ParseError {
Dummy,
}
#[derive(Debug)]
struct ResourceWithErr<'a>((Resource<'a>, Option<Vec<ParseError>>));
impl<'a> From<&'a String> for ResourceWithErr<'a> {
fn from(source: &'a String) -> Self {
match parse_runtime(source) {
Ok(resource) => Self((resource, None)),
Err((resource, errors)) => Self((resource, Some(errors))),
}
}
}
self_cell!(
struct FluentResource {
#[from]
owner: String,
#[covariant]
dependent: ResourceWithErr,
}
impl {Debug}
);
impl FluentResource {
fn try_new(source: String) -> Result<Self, (Self, Vec<ParseError>)> {
let cell = Self::new(source);
if let Some(errors) = cell.borrow_dependent().0 .1.as_ref() {
let cloned_errors = errors.clone();
Err((cell, cloned_errors))
} else {
Ok(cell)
}
}
}
fn main() {
dbg!(FluentResource::try_new("fox = cat + dog".into()).unwrap());
dbg!(FluentResource::try_new("fox = bad_dog".into()).unwrap_err());
} In general the Let me know if this works for you. |
We spent quite a bit collecting feedback on various pros and cons - projectfluent/fluent-rs#219 - it's not trivial what the right approach should be and I expect to continue iterating on it as the whole ecosystem matures and patterns emerge. What I'm concerned about is that effectively your library locks that by making it opaque.
I don't think it does, and I don't think its necessarily a bad thing. The value your crate provides is not limited to a single use case (even one that inspired it), and I think at this point trying to find a balance between what Fluent needs and what you offer becomes a limitation to your ability to release and get external testing and validation. I'd suggest release what you have and keep a bug open on future possibilities of aligning with Fluent needs. Some of the feedback you'll get, and some of the feedback Fluent will get, may get us more aligned and we should keep an eye on that, but I would suggest unblocking the next release of once_self_cell atm. |
I see where you are coming from. Could you at least explain why. |
I have a system that works both for my testers and in production at scale. One API decision (way to return success with failures) Fluent made seems to be causing strong design challenges for against the design decisions you made and "just don't fit". Since both Fluent API and your API are still in flux, I'm leaning toward recognizing that outcome of our exploration here and moving on to avoid preventing you from releasing the next revision of your crate. Releasing it is important for I'd prefer to continue monitoring for potential future alignment as the API of |
Thanks for the explanation. The situation might not be as stuck as it appears to you. Some further thinking made the situation more clear to me. You have a constructor for your dependent that doesn't only produce the lifetime dependent value, but also some other unrelated value. It shouldn't be too hard to create a third constructor type that covers this use case, it shouldn't bloat the API too much either. Why I'm keen on finding a solution here is not entirely selfless. Having a semi-popular crate successfully transition, would both signal to me that this crate actually is a valid competitor to the ones it tries to be an alternative for, and it could help others have more confidence. |
I agree with that goal! I merely suggest that we don't need to achieve it in this pre-release :) |
How about this, let's timebox this PR to max Sunday 25.04.2021. In that meantime we'll try to find a solution, if not, all good and we'll continue this as an issue. |
This allows much more flexible construction. But comes at the cost of not allowing the automatic Clone impl. It ought to be safe on current Rust, but we might have to revise this specific constructor with future Rust versions, when expressing a closure that captures a reference that outlives the hrtb function signature ref it's passed into becomes possible.
@zbraniecki this latest commit introduced a new constructor type that should cover your use case. |
In line with our agreed timebox I'm closing this PR. Please let me know if this works for you, also in terms of performance. If not we'll continue your topic in a separate issue. |
I tried to apply the |
Unless I'm missing something shouldn't the same approach used before https://github.com/projectfluent/fluent-rs/pull/221/files#diff-73bb1d907649cc571c753052726efc674e5b561ed29e48d8d7e46d55ba3f8030L77 work here too. |
@zbraniecki friendly ping, it be great to get this resolved. If this latest suggestion of mine doesn't work out, please open a new issue. Discussion in a closed PR isn't ideal. |
This is a ground up rewrite that addresses all outstanding issues:
self_cell
(lazy is opt in via custom dependent type)I will merge this in the absence of feedback, one week from now, Tue 20.04.2021.