Can't map a vector of fields
Closed this issue · 5 comments
I'm in the process of writing some convenience methods to access data and format it somewhat, but ran into this little gem along the way:
error[E0599]: the method `map` exists for struct `Vec<Field<'_>>`, but its trait bounds were not satisfied
--> src/main.rs:45:76
|
45 | let pid: &GenericSegment = generics.iter().find_map(|s| match s.fields.map(|f| f.value).collect().first() {
| ^^^ method cannot be called on `Vec<Field<'_>>` due to unsatisfied trait bounds
|
::: /home/username/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:374:1
|
374 | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
| ------------------------------------------------------------------------------------------------ doesn't satisfy `Vec<Field<'_>>: Iterator`
|
= note: the following trait bounds were not satisfied:
`Vec<Field<'_>>: Iterator`
which is required by `&mut Vec<Field<'_>>: Iterator`
`[Field<'_>]: Iterator`
which is required by `&mut [Field<'_>]: Iterator`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0599`.
error: could not compile `hl7test`
Having a bunch of lifetime related fun too - writing functions outside the library for subsequent import into it is a bit harder than one would think because everything holds lifetime references to pieces of the overall struct. Good learning experience though :).
I think this is related:
rust-hl7(feature/message_convenience)$ cargo build
Compiling rust-hl7 v0.2.2 (/opt/code/Rust/rust-hl7)
error[E0277]: a value of type `Vec<&GenericSegment<'_>>` cannot be built from an iterator over elements of type `&&GenericSegment<'_>`
--> src/message.rs:57:91
|
57 | let found = generics.iter().filter(|s| s.fields.first().unwrap().value() == name).collect();
| ^^^^^^^ value of type `Vec<&GenericSegment<'_>>` cannot be built from `std::iter::Iterator<Item=&&GenericSegment<'_>>`
|
= help: the trait `FromIterator<&&GenericSegment<'_>>` is not implemented for `Vec<&GenericSegment<'_>>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
error: could not compile `rust-hl7`
The code causing this (will be PRd once i have it working) is:
/// Extracts all generic elements to owned objects for external use
pub fn generics(&self) -> Result<Vec<&generic::GenericSegment>, Hl7ParseError> {
let generics: Vec<&generic::GenericSegment> = self.segments.iter()
.filter_map(|s| match s {
segments::Segment::Generic(x) => Some(x),
_ => None,
}).map(|g| g.clone().to_owned()).collect();
Ok(generics)
}
/// Extracts generic elements to owned objects for external use by matching first field to name
pub fn segments_by_name(&self, name: &str) -> Result<Vec<&generic::GenericSegment>, Hl7ParseError> {
let generics = Message::generics(self).unwrap();
let found = generics.iter().filter(|s| s.fields.first().unwrap().value() == name).collect();
Ok(found)
}
On a related note - i think that once i have these convenience methods working throughout the lib, we should be able to leverage them with either a giant enum or a smart macro of some sort to do typed conversions using the other lib's structure definitions. I'm still not macro-level-l33t in Rust (though they look somewhat similar to Crystal's), but either will have bloody fingertips when this is done or understand those a bit better.
Ohh boy... I'm starting to wonder if your rust is more advanced than mine at this point!
I understand the lifetime pain... I originally started to write this without lifetimes for simplicity (i.e. lot's of string copying) but then moved to try and build it as efficiently as I could as a learning exercise due to the horrific perf characteristics of the commercial integration engine I was dealing with at the time. That obviously entails handing back slices of the original message, which is in rust requires the deep dive into lifetimes.
There's a commented out method from the pre-lifetimes version, I'll go have a look at an equivalent.
I just found your PR so I'll stop looking into my own impl for these.
Is your client code in github? I was hoping that users of the library would be able to use it even with the lifetimes given the data is readonly? I'd like to know if that assumption is totally simplistic on my part and it's impossible to do what you want to do with the slicing behaviour...
So i think i need to rephrase this a bit, stdby for new issue :).