diff options
Diffstat (limited to 'support/texlab/crates/bibtex-utils/src/field/number.rs')
-rw-r--r-- | support/texlab/crates/bibtex-utils/src/field/number.rs | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/support/texlab/crates/bibtex-utils/src/field/number.rs b/support/texlab/crates/bibtex-utils/src/field/number.rs new file mode 100644 index 0000000000..227f3d5b75 --- /dev/null +++ b/support/texlab/crates/bibtex-utils/src/field/number.rs @@ -0,0 +1,60 @@ +use std::fmt; + +use syntax::bibtex::Value; + +use super::text::TextFieldData; + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)] +pub enum NumberField { + Edition, + Number, + Pages, + PageTotal, + Part, + Volume, + Volumes, +} + +impl NumberField { + pub fn parse(input: &str) -> Option<Self> { + Some(match input.to_ascii_lowercase().as_str() { + "edition" => Self::Edition, + "number" => Self::Number, + "pages" => Self::Pages, + "pagetotal" => Self::PageTotal, + "part" => Self::Part, + "volume" => Self::Volume, + "volumes" => Self::Volumes, + _ => return None, + }) + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Hash)] +pub enum NumberFieldData { + Scalar(u32), + Range(u32, u32), + Other(String), +} + +impl fmt::Display for NumberFieldData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Scalar(value) => write!(f, "{}", value), + Self::Range(start, end) => write!(f, "{}-{}", start, end), + Self::Other(value) => write!(f, "{}", value.replace("--", "-")), + } + } +} + +impl NumberFieldData { + pub fn parse(value: &Value) -> Option<Self> { + let TextFieldData { text } = TextFieldData::parse(value)?; + text.split_once("--") + .or_else(|| text.split_once('-')) + .and_then(|(a, b)| Some((a.parse().ok()?, b.parse().ok()?))) + .map(|(a, b)| Self::Range(a, b)) + .or_else(|| text.parse().ok().map(Self::Scalar)) + .or(Some(Self::Other(text))) + } +} |