diff options
| -rw-r--r-- | src/bin.rs | 1 | ||||
| -rw-r--r-- | src/document_tree.rs | 1 | ||||
| -rw-r--r-- | src/document_tree/elements.rs | 16 | ||||
| -rw-r--r-- | src/document_tree/extra_attributes.rs | 21 | ||||
| -rw-r--r-- | src/document_tree/serde_util.rs | 12 | ||||
| -rw-r--r-- | src/lib.rs | 1 | ||||
| -rw-r--r-- | src/parser/conversion.rs | 25 | ||||
| -rw-r--r-- | src/target.rs | 42 | 
8 files changed, 72 insertions, 47 deletions
| @@ -2,6 +2,7 @@  pub mod document_tree;  pub mod parser; +pub mod target;  use structopt::StructOpt; diff --git a/src/document_tree.rs b/src/document_tree.rs index 749654c..3d983da 100644 --- a/src/document_tree.rs +++ b/src/document_tree.rs @@ -3,7 +3,6 @@  #[macro_use]  mod macro_util; -mod serde_util;  pub mod elements;  pub mod element_categories; diff --git a/src/document_tree/elements.rs b/src/document_tree/elements.rs index 2b99d97..5f669ae 100644 --- a/src/document_tree/elements.rs +++ b/src/document_tree/elements.rs @@ -1,7 +1,6 @@  use serde_derive::Serialize; -use url::Url; -use super::serde_util::serialize_opt_url; +use crate::target;  use super::extra_attributes::{self,ExtraAttributes};  use super::element_categories::*; @@ -15,8 +14,8 @@ pub trait Element {  	fn     ids_mut(&mut self) -> &mut Vec<String>;  	fn   names    (&    self) -> &    Vec<String>;  	fn   names_mut(&mut self) -> &mut Vec<String>; -	fn  source    (&    self) -> &    Option<Url>; -	fn  source_mut(&mut self) -> &mut Option<Url>; +	fn  source    (&    self) -> &    Option<target::Target>; +	fn  source_mut(&mut self) -> &mut Option<target::Target>;  	fn classes    (&    self) -> &    Vec<String>;  	fn classes_mut(&mut self) -> &mut Vec<String>;  } @@ -25,8 +24,7 @@ pub trait Element {  pub struct CommonAttributes {  	ids:     Vec<String>,  	names:   Vec<String>, -	#[serde(serialize_with = "serialize_opt_url")] -	source:  Option<Url>, +	source:  Option<target::Target>,  	classes: Vec<String>,  	//left out dupnames  } @@ -41,8 +39,8 @@ macro_rules! impl_element { ($name:ident) => (  		fn     ids_mut(&mut self) -> &mut Vec<String> { &mut self.common.ids     }  		fn   names    (&    self) -> &    Vec<String> { &    self.common.names   }  		fn   names_mut(&mut self) -> &mut Vec<String> { &mut self.common.names   } -		fn  source    (&    self) -> &    Option<Url> { &    self.common.source  } -		fn  source_mut(&mut self) -> &mut Option<Url> { &mut self.common.source  } +		fn  source    (&    self) -> &    Option<target::Target> { &    self.common.source  } +		fn  source_mut(&mut self) -> &mut Option<target::Target> { &mut self.common.source  }  		fn classes    (&    self) -> &    Vec<String> { &    self.common.classes }  		fn classes_mut(&mut self) -> &mut Vec<String> { &mut self.common.classes }  	} @@ -251,7 +249,7 @@ impl_elems!(  );  impl<'a> From<&'a str> for TextOrInlineElement { -	fn from(s: &'a str) -> TextOrInlineElement { +	fn from(s: &'a str) -> Self {  		s.to_owned().into()  	}  } diff --git a/src/document_tree/extra_attributes.rs b/src/document_tree/extra_attributes.rs index 2019dec..c926113 100644 --- a/src/document_tree/extra_attributes.rs +++ b/src/document_tree/extra_attributes.rs @@ -1,8 +1,6 @@ -use url::Url; -  use serde_derive::Serialize; -use super::serde_util::{serialize_url,serialize_opt_url}; +use crate::target;  use super::attribute_types::{FixedSpace,ID,NameToken,AlignHV,AlignH,Measure,EnumeratedListType};  pub trait ExtraAttributes<A> { @@ -32,23 +30,20 @@ impl_extra!(DoctestBlock { space: FixedSpace });  impl_extra!(SubstitutionDefinition { ltrim: Option<bool>, rtrim: Option<bool> });  impl_extra!(Comment { space: FixedSpace });  impl_extra!(Target { -	#[serde(serialize_with = "serialize_opt_url")] -	refuri: Option<Url>, +	refuri: Option<target::Target>,  	refid: Option<ID>,  	refname: Vec<NameToken>,  	anonymous: bool,  });  impl_extra!(Raw { space: FixedSpace, format: Vec<NameToken> });  impl_extra!(#[derive(Debug,Serialize)] Image { -	#[serde(serialize_with = "serialize_url")] -	uri: Url, +	uri: target::Target,  	align: Option<AlignHV>,  	alt: Option<String>,  	height: Option<Measure>,  	width: Option<Measure>,  	scale: Option<u8>, -	#[serde(serialize_with = "serialize_opt_url")] -	target: Option<Url>,  // Not part of the DTD but a valid argument +	target: Option<target::Target>,  // Not part of the DTD but a valid argument  });  //bools usually are XML yesorno. “auto” however either exists and is set to something random like “1” or doesn’t exist @@ -66,8 +61,7 @@ impl_extra!(OptionArgument { delimiter: Option<String> });  impl_extra!(Reference {  	name: Option<String>, -	#[serde(serialize_with = "serialize_opt_url")] -	refuri: Option<Url>, +	refuri: Option<target::Target>,  	refid: Option<ID>,  	refname: Vec<NameToken>,  }); @@ -78,8 +72,7 @@ impl_extra!(Problematic { refid: Option<ID> });  //also have non-inline versions. Inline image is no figure child, inline target has content  impl_extra!(TargetInline { -	#[serde(serialize_with = "serialize_opt_url")] -	refuri: Option<Url>, +	refuri: Option<target::Target>,  	refid: Option<ID>,  	refname: Vec<NameToken>,  	anonymous: bool, @@ -88,7 +81,7 @@ impl_extra!(RawInline { space: FixedSpace, format: Vec<NameToken> });  pub type ImageInline = Image;  impl Image { -	pub fn new(uri: Url) -> Image { Image { +	pub fn new(uri: target::Target) -> Image { Image {  		uri: uri,  		align: None,  		alt: None, diff --git a/src/document_tree/serde_util.rs b/src/document_tree/serde_util.rs deleted file mode 100644 index 2e24309..0000000 --- a/src/document_tree/serde_util.rs +++ /dev/null @@ -1,12 +0,0 @@ -use url::Url; - -pub fn serialize_url<S>(url: &Url, serializer: S) -> Result<S::Ok, S::Error> where S: serde::ser::Serializer { -	serializer.serialize_str(url.as_str()) -} - -pub fn serialize_opt_url<S>(url_opt: &Option<Url>, serializer: S) -> Result<S::Ok, S::Error> where S: serde::ser::Serializer { -	match url_opt { -		Some(ref url) => serializer.serialize_some(url.as_str()), -		None          => serializer.serialize_none(), -	} -} @@ -3,3 +3,4 @@  pub mod document_tree;  pub mod parser;  pub mod renderer; +pub mod target; diff --git a/src/parser/conversion.rs b/src/parser/conversion.rs index 0288c4c..6d10744 100644 --- a/src/parser/conversion.rs +++ b/src/parser/conversion.rs @@ -37,22 +37,25 @@ impl<'l, R> PairExt<R> for Pair<'l, R> where R: pest::RuleType {  pub fn convert_document(pairs: Pairs<Rule>) -> Result<e::Document, Error> { -    let structural_elems = pairs.map(convert_ssubel).collect::<Result<_,_>>()?; +    let structural_elems = pairs.map(convert_ssubel) +        .filter_map(|elem| match elem { Ok(Some(e)) => Some(Ok(e)), Err(e) => Some(Err(e)), Ok(None) => None }) +        .collect::<Result<_,_>>()?;      Ok(e::Document::with_children(structural_elems))  } -fn convert_ssubel(pair: Pair<Rule>) -> Result<c::StructuralSubElement, Error> { +fn convert_ssubel(pair: Pair<Rule>) -> Result<Option<c::StructuralSubElement>, Error> {      // TODO: This is just a proof of concep. Keep closely to DTD in final version! -    match pair.as_rule() { -        Rule::title            => Ok(convert_title(pair).into()), -        Rule::paragraph        => Ok(e::Paragraph::with_children(vec![pair.as_str().into()]).into()), -        Rule::target           => Ok(convert_target(pair)?.into()), -        Rule::substitution_def => Ok(convert_substitution_def(pair)?.into()), -        Rule::admonition_gen   => Ok(convert_admonition_gen(pair)?.into()), -        Rule::image            => Ok(convert_image::<e::Image>(pair)?.into()), -        rule => Err(ConversionError::UnknownRuleError { rule }.into()), -    } +    Ok(Some(match pair.as_rule() { +        Rule::title            => convert_title(pair).into(), +        Rule::paragraph        => e::Paragraph::with_children(vec![pair.as_str().into()]).into(), +        Rule::target           => convert_target(pair)?.into(), +        Rule::substitution_def => convert_substitution_def(pair)?.into(), +        Rule::admonition_gen   => convert_admonition_gen(pair)?.into(), +        Rule::image            => convert_image::<e::Image>(pair)?.into(), +        Rule::EOI              => return Ok(None), +        rule => return Err(ConversionError::UnknownRuleError { rule }.into()), +    }))  } diff --git a/src/target.rs b/src/target.rs new file mode 100644 index 0000000..2752097 --- /dev/null +++ b/src/target.rs @@ -0,0 +1,42 @@ +use std::path::PathBuf; +use std::str::FromStr; +use std::string::ParseError; + +use url::{self,Url}; +use serde_derive::Serialize; + + +#[derive(Debug, Serialize)] +pub enum Target { +    #[serde(serialize_with = "serialize_url")] +    Url(Url), +    Path(PathBuf), +} + +impl From<Url> for Target { +    fn from(url: Url) -> Self { +        Target::Url(url) +    } +} + +impl From<PathBuf> for Target { +    fn from(path: PathBuf) -> Self { +        Target::Path(path) +    } +} + + +impl FromStr for Target { +    type Err = ParseError; +	fn from_str(input: &str) -> Result<Self, Self::Err> { +        Ok(match Url::parse(input) { +            Ok(url) => url.into(), +            Err(_) => PathBuf::from(input).into(), +        }) +    } +} + + +pub fn serialize_url<S>(url: &Url, serializer: S) -> Result<S::Ok, S::Error> where S: serde::ser::Serializer { +	serializer.serialize_str(url.as_str()) +} | 
