diff --git a/four-bar-ui/src/app/proj/impl_proj.rs b/four-bar-ui/src/app/proj/impl_proj.rs index 212ee823..08aa1c1e 100644 --- a/four-bar-ui/src/app/proj/impl_proj.rs +++ b/four-bar-ui/src/app/proj/impl_proj.rs @@ -1,5 +1,6 @@ use super::*; use four_bar::{csv, efd, fb, NormFourBar, SNormFourBar}; +use std::path::Path; macro_rules! hotkey { ($ui:ident, $mod1:ident + $key:ident) => { @@ -88,7 +89,7 @@ impl Project { fn name(self: &Self) -> String; fn preload(self: &mut Self); fn set_path(self: &mut Self, path: PathBuf); - fn path(self: &Self) -> Option<&PathBuf>; + fn path(self: &Self) -> Option<&Path>; fn is_unsaved(self: &Self) -> bool; fn mark_saved(self: &mut Self); } @@ -286,7 +287,7 @@ where io::save_csv_ask(&get_curve(*pivot, &self.fb, cfg.res)); } if small_btn(ui, "🗐", "Copy") { - let t = csv::csv_string(get_curve(*pivot, &self.fb, cfg.res)).unwrap(); + let t = csv::to_string(get_curve(*pivot, &self.fb, cfg.res)).unwrap(); ui.output_mut(|s| s.copied_text = t); } }); @@ -358,24 +359,22 @@ where if cfg!(target_arch = "wasm32") { return; } - if let Some(fb) = self - .path - .as_ref() - .and_then(|p| std::fs::File::open(p).ok()) - .and_then(|r| ron::de::from_reader(r).ok()) - { - if self.fb != fb { + // FIXME: Try block, ignore errors + (|| { + let r = std::fs::File::open(self.path.as_ref()?).ok()?; + if self.fb != ron::de::from_reader(r).ok()? { self.unsaved = true; } - } + Some(()) + })(); } fn set_path(&mut self, path: PathBuf) { self.path.replace(path); } - fn path(&self) -> Option<&PathBuf> { - self.path.as_ref() + fn path(&self) -> Option<&Path> { + self.path.as_deref() } fn is_unsaved(&self) -> bool { diff --git a/four-bar-ui/src/app/syn.rs b/four-bar-ui/src/app/syn.rs index 09a9e131..a8ccaae7 100644 --- a/four-bar-ui/src/app/syn.rs +++ b/four-bar-ui/src/app/syn.rs @@ -140,8 +140,8 @@ impl Synthesis { ui.horizontal_wrapped(|ui| { if ui.button("🗐 Copy CSV").clicked() { let text = match &self.target { - io::Curve::P(t) => csv::csv_string(t).unwrap(), - io::Curve::S(t) => csv::csv_string(t).unwrap(), + io::Curve::P(t) => csv::to_string(t).unwrap(), + io::Curve::S(t) => csv::to_string(t).unwrap(), }; ui.output_mut(|s| s.copied_text = text); } diff --git a/four-bar-ui/src/io.rs b/four-bar-ui/src/io.rs index 819fbe0e..fc4110fa 100644 --- a/four-bar-ui/src/io.rs +++ b/four-bar-ui/src/io.rs @@ -288,13 +288,13 @@ where pub(crate) fn save_csv_ask(c: &[S]) where - S: serde::Serialize + Clone, + S: serde::Serialize, { save_ask( "curve.csv", CSV_FMT, CSV_EXT, - |w| csv::dump_csv(w, c), + |w| csv::to_writer(w, c), |_| (), ); } @@ -372,11 +372,11 @@ impl Curve { where R: std::io::Read + std::io::Seek, { - if let Ok(c) = csv::parse_csv(&mut r) { + if let Ok(c) = csv::from_reader(&mut r) { Ok(Self::S(c)) } else { r.rewind()?; - Ok(Self::P(csv::parse_csv(r)?)) + Ok(Self::P(csv::from_reader(r)?)) } } diff --git a/four-bar/src/csv.rs b/four-bar/src/csv.rs index d4527025..d20a16fe 100644 --- a/four-bar/src/csv.rs +++ b/four-bar/src/csv.rs @@ -2,32 +2,32 @@ pub use csv::Error; use csv::{ReaderBuilder, Writer}; use serde::{de::DeserializeOwned, Serialize}; +use std::io::ErrorKind::InvalidData; /// Parse CSV from string. -pub fn parse_csv(r: R) -> Result, Error> +pub fn from_reader(r: R) -> Result, Error> where R: std::io::Read, D: DeserializeOwned, { - let data = ReaderBuilder::new() + ReaderBuilder::new() .has_headers(false) .comment(Some(b'#')) .from_reader(r) .deserialize() - .collect::, _>>()?; - if data.is_empty() { - Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "No data").into()) - } else { - Ok(data) - } + .collect::, _>>() + .and_then(|data| match data.is_empty() { + true => Err(std::io::Error::new(InvalidData, "Empty data"))?, + false => Ok(data), + }) } /// Dump CSV to a writer. -pub fn dump_csv<'a, W, C, S>(w: W, c: C) -> Result<(), csv::Error> +pub fn to_writer(w: W, c: C) -> Result<(), csv::Error> where W: std::io::Write, C: AsRef<[S]>, - S: Serialize + Clone + 'a, + S: Serialize, { let mut w = Writer::from_writer(w); c.as_ref().iter().try_for_each(|c| w.serialize(c))?; @@ -36,12 +36,12 @@ where } /// Dump CSV to string. -pub fn csv_string<'a, C, S>(c: C) -> Result +pub fn to_string(c: C) -> Result where C: AsRef<[S]>, - S: Serialize + Clone + 'a, + S: Serialize, { let mut w = Vec::new(); - dump_csv(&mut w, c)?; + to_writer(&mut w, c)?; Ok(String::from_utf8(w).unwrap()) } diff --git a/four-bar/src/plot.rs b/four-bar/src/plot.rs index 178d8ec9..161cb439 100644 --- a/four-bar/src/plot.rs +++ b/four-bar/src/plot.rs @@ -579,10 +579,7 @@ impl<'a, 'b, M: Clone, C: Clone> FigureBase<'a, 'b, M, C> { #[inline] fn get_family(&self) -> &str { const DEFAULT_FONT: &str = "Times New Roman"; - self.font_family - .as_ref() - .map(|s| s.as_ref()) - .unwrap_or(DEFAULT_FONT) + self.font_family.as_deref().unwrap_or(DEFAULT_FONT) } pub(crate) fn get_font(&self) -> TextStyle {