summaryrefslogtreecommitdiff
path: root/support/texlab/crates/bibtex-utils/src/field/number.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/crates/bibtex-utils/src/field/number.rs')
-rw-r--r--support/texlab/crates/bibtex-utils/src/field/number.rs60
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)))
+ }
+}