diff options
author | Neil Hansen <51208969+neilyio@users.noreply.github.com> | 2024-04-07 13:38:47 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-07 13:38:47 -0500 |
commit | 9628c7e52006fe248978d9a926e161696987f5c5 (patch) | |
tree | 0296339ea5e23b9aa26e83d7147e86dd51005886 | |
parent | 17528729b51578c034cec5efd8599535076a8dd3 (diff) |
Fix empty output in csv_vectors example (#89)
-rw-r--r-- | examples/csv_vectors.rs | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/examples/csv_vectors.rs b/examples/csv_vectors.rs index 78ed6af..9d5e0ea 100644 --- a/examples/csv_vectors.rs +++ b/examples/csv_vectors.rs @@ -3,9 +3,7 @@ extern crate serde; #[macro_use] extern crate serde_derive; extern crate serde_qs as qs; - use serde::de::DeserializeOwned; - use std::default::Default; #[derive(Debug, PartialEq, Deserialize, Serialize)] @@ -35,21 +33,25 @@ fn deserialize_sequence() { fn from_csv<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error> where D: serde::Deserializer<'de>, - T: DeserializeOwned, + T: DeserializeOwned + std::str::FromStr, + <T as std::str::FromStr>::Err: std::fmt::Debug, { deserializer.deserialize_str(CSVVecVisitor::<T>::default()) } /// Visits a string value of the form "v1,v2,v3" into a vector of bytes Vec<u8> -struct CSVVecVisitor<T: DeserializeOwned>(std::marker::PhantomData<T>); +struct CSVVecVisitor<T: DeserializeOwned + std::str::FromStr>(std::marker::PhantomData<T>); -impl<T: DeserializeOwned> Default for CSVVecVisitor<T> { +impl<T: DeserializeOwned + std::str::FromStr> Default for CSVVecVisitor<T> { fn default() -> Self { CSVVecVisitor(std::marker::PhantomData) } } -impl<'de, T: DeserializeOwned> serde::de::Visitor<'de> for CSVVecVisitor<T> { +impl<'de, T: DeserializeOwned + std::str::FromStr> serde::de::Visitor<'de> for CSVVecVisitor<T> +where + <T as std::str::FromStr>::Err: std::fmt::Debug, // handle the parse error in a generic way +{ type Value = Vec<T>; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { @@ -60,12 +62,31 @@ impl<'de, T: DeserializeOwned> serde::de::Visitor<'de> for CSVVecVisitor<T> { where E: serde::de::Error, { + // Treat the comma-separated string as a single record in a CSV. + let mut rdr = csv::ReaderBuilder::new() + .has_headers(false) + .from_reader(s.as_bytes()); + + // Try to get the record and collect its values into a vector. let mut output = Vec::new(); - let mut items = csv::Reader::from_reader(s.as_bytes()); - for res in items.deserialize() { - let item: T = res - .map_err(|e| E::custom(format!("could not deserialize sequence value: {:?}", e)))?; - output.push(item); + for result in rdr.records() { + match result { + Ok(record) => { + for field in record.iter() { + output.push( + field + .parse::<T>() + .map_err(|_| E::custom("Failed to parse field"))?, + ); + } + } + Err(e) => { + return Err(E::custom(format!( + "could not deserialize sequence value: {:?}", + e + ))); + } + } } Ok(output) |