-
Notifications
You must be signed in to change notification settings - Fork 5
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
Adds fluid methods to Pointer
#67
Conversation
@asmello do you have any opinion on the names? I struggled with them. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files
|
I'm not convinced this is the right approach. I feel like Which potentially means the fluent API should exist in |
This is consistent with |
Fair point. I guess paths have some special semantics that make them more like a struct than a collection. It's kinda interesting, not sure the I'm happy with the first two names — they're pretty descriptive, a bit on the long side but I think we don't want to encourage using this API too much, given the potential for allocation abuse, so that's actually good. I think we can do better with the last one though. How about EDITIt would make sense to call it So perhaps |
Yea, hopefully folks won't shoot themselves in the foot with it. I'm hoping the ergonomics of it are worth it. Maybe I should add a note about how they allocate and that they above should be avoided. Oh, I like Edit |
Definitely! This is well documented in the If you're happy with
I don't think so, for one that trait is nightly and for another its API is different, we'd need to use it like |
Ah, okay. I wasn't exactly certain how the call looked. From the trait, it seemed straight forward in that it added a I'll rename to Then again.. maybe its not worth the savings in loc. |
Yeah it's fine to try this out, especially given the |
src/pointer.rs
Outdated
where | ||
T: Into<Token<'t>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nit, but I think impl Into<Token<'_>>
would be cleaner (unsure about whether the lifetime can be elided but I think so)
Just a thought, but curious how you start with I'm thinking of some network coding I've been doing where I found that what works best is to allocate a single permanent buffer at a high level, sift it down the abstraction layers up to the point where I do a socket read, and then on the way back up all the parsing (well, most of it) can be done with zero copies. It's quite neat from a lifetime management perspective, but most importantly it helps monstrously with reducing allocations. It's quite easy and tempting to allocate a fresh buffer for every read (or every read site) but that's also easily ends up being a bottleneck. Even if it's a local (but permanent) buffer, you end up having to copy on the way up. |
Nah, I can't reuse the buffer as they get stored. This is a function that resolves a source and inserts it into my source database : async fn resolve_path<'int, R: 'static + Resolve>(
sources: &'int mut Sources,
resolver: &R,
uri: &AbsoluteUri,
base: AbsoluteUri,
fragment: String,
) -> Result<Resolved, Error<R>> {
let resolved_root = resolve_root(sources, resolver, &base).await?;
let located = resolved_root.located;
let document_key = resolved_root.document_key;
let relative_path = Pointer::parse(&fragment).map_err(|source| Error::InvalidPointer {
uri: uri.clone(),
source,
})?;
let mut absolute_path = sources.source(resolved_root.source_key).path().to_buf();
absolute_path.append(&relative_path);
let source_key = sources
.link(New {
uri: uri.clone(),
document_key,
absolute_path,
fragment: Some(Fragment::Pointer(relative_path.to_buf())),
})
.map_err(|source| match source {
LinkError::InvalidPath(err) => Error::PathNotFound {
uri: uri.clone(),
source: err,
},
LinkError::SourceConflict(err) => unreachable!(
"\n\nsource conflict:\n\nuri: {uri}\ndocument_key: {document_key:?}\nerr: {err}",
),
})?;
Ok(Resolved::Source(resolved::Src {
link_created: true,
source_key,
document_key,
located,
}))
} |
Well, fair enough. Was worth a shot. |
Absolutely, and I appreciate it. I updated the docs to reflect std with an additional note that may be a bit too much. |
@asmello (sorry, disregard) I tried using the inline, pub fn push_back<'t, T>(&mut self, token: impl Into<Token<'t>>) {
self.0.push('/');
self.0.push_str(token.into().encoded());
}
pub fn with_trailing_token<'t>(&self, token: impl Into<Token<'t>>) -> PointerBuf {
let mut buf = self.to_buf();
buf.push_back(token.into());
buf
} ▶ cargo check
Checking jsonptr v0.6.0 (/Users/chance/dev/jsonptr)
error[E0282]: type annotations needed
--> src/pointer.rs:442:13
|
442 | buf.push_back(token.into());
| ^^^^^^^^^ cannot infer type for type parameter `T` declared on the method `push_back`
error[E0282]: type annotations needed
--> src/pointer.rs:462:13
|
462 | buf.push_front(token);
| ^^^^^^^^^^ cannot infer type for type parameter `T` declared on the method `push_front`
For more information about this error, try `rustc --explain E0282`. EDITAhh, I'm an idiot. I forgot to dump |
@asmello thanks for the help & review. |
solves #31 by adding fluid methods to
Pointer
:with_leading_token
- prepends a tokenwith_trailing_token
- appends a tokenwith_appended
- appends a pointer