From: Ian Jackson Date: Tue, 8 Sep 2020 23:34:54 +0000 (+0100) Subject: parse library file X-Git-Tag: otter-0.2.0~958 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=671baed15ba1ce0bf82dfcb23137c91041bb4a8d;p=otter.git parse library file Signed-off-by: Ian Jackson --- diff --git a/src/bin/otterlib.rs b/src/bin/otterlib.rs index bd903b6f..a8752b0b 100644 --- a/src/bin/otterlib.rs +++ b/src/bin/otterlib.rs @@ -2,8 +2,7 @@ pub use otter::imports::*; #[throws(anyhow::Error)] fn main(){ - let mut s = String::new(); - io::stdin().read_to_string(&mut s)?; - let l : shapelib::Library = toml::from_str(&s)?; + let f = env::args().nth(1).unwrap(); + let l = shapelib::Library::load(&f)?; dbg!(l); } diff --git a/src/shapelib.rs b/src/shapelib.rs index 37daf3e9..98502bc1 100644 --- a/src/shapelib.rs +++ b/src/shapelib.rs @@ -12,15 +12,16 @@ pub struct Library { #[derive(Deserialize,Debug)] pub struct Section { - pub shape: Box, + pub outline: Box, pub size: Vec, pub middle: Option>, pub category: String, pub files: FileList, - pub scraper: toml::Value, + pub scraper: Option, } #[derive(Deserialize,Debug)] +#[serde(try_from="&str")] pub struct FileList (Vec); #[derive(Deserialize,Debug)] @@ -29,11 +30,56 @@ pub struct FileEntry { pub desc: Html, } -#[typetag::deserialize(tag="outline")] +#[typetag::deserialize] pub trait OutlineSpec : Debug { } +#[derive(Error,Debug)] +pub enum LibraryLoadError{ + #[error(transparent)] + TomlParseError(#[from] toml::de::Error), + #[error("error reading/opening library file: {0}")] + FileError(#[from] io::Error), + #[error("{:?}",&self)] + FilesListLineMissingWhitespace(usize), +} + +impl Library { + #[throws(LibraryLoadError)] + pub fn load(path: &str) -> Library { + let f = File::open(path)?; + let mut f = BufReader::new(f); + let mut s = String::new(); + f.read_to_string(&mut s).unwrap(); + let l : shapelib::Library = toml::from_str(&s)?; + l + } +} + +type LLE = LibraryLoadError; + #[derive(Deserialize,Debug)] -pub struct Circle { } +struct Circle { } #[typetag::deserialize] impl OutlineSpec for Circle { } + +impl TryFrom<&str> for FileList { + type Error = LLE; + #[throws(LLE)] + fn try_from(s: &str) -> FileList { + let mut o = Vec::new(); + for (lno,l) in s.lines().enumerate() { + let l = l.trim(); + if l=="" || l.starts_with("#") { continue } + let sp = l.find(|c:char| c.is_ascii_whitespace()) + .ok_or(LLE::FilesListLineMissingWhitespace(lno))?; + let (lhs, rhs) = l.split_at(sp); + let rhs = rhs.trim(); + o.push(FileEntry{ + filespec: lhs.to_owned(), + desc: Html(rhs.to_owned()), + }); + } + FileList(o) + } +}