summaryrefslogtreecommitdiffstats
path: root/vendor/time-macros/src/format_description/parse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/time-macros/src/format_description/parse.rs')
-rw-r--r--vendor/time-macros/src/format_description/parse.rs84
1 files changed, 84 insertions, 0 deletions
diff --git a/vendor/time-macros/src/format_description/parse.rs b/vendor/time-macros/src/format_description/parse.rs
new file mode 100644
index 000000000..19c7bf608
--- /dev/null
+++ b/vendor/time-macros/src/format_description/parse.rs
@@ -0,0 +1,84 @@
+use proc_macro::Span;
+
+use crate::format_description::component::{Component, NakedComponent};
+use crate::format_description::error::InvalidFormatDescription;
+use crate::format_description::{helper, modifier, FormatItem};
+use crate::Error;
+
+struct ParsedItem<'a> {
+ item: FormatItem<'a>,
+ remaining: &'a [u8],
+}
+
+fn parse_component(mut s: &[u8], index: &mut usize) -> Result<Component, InvalidFormatDescription> {
+ s = helper::consume_whitespace(s, index);
+
+ let component_index = *index;
+ let whitespace_loc = s
+ .iter()
+ .position(u8::is_ascii_whitespace)
+ .unwrap_or(s.len());
+ *index += whitespace_loc;
+ let component_name = &s[..whitespace_loc];
+ s = &s[whitespace_loc..];
+ s = helper::consume_whitespace(s, index);
+
+ Ok(NakedComponent::parse(component_name, component_index)?
+ .attach_modifiers(modifier::Modifiers::parse(component_name, s, index)?))
+}
+
+fn parse_literal<'a>(s: &'a [u8], index: &mut usize) -> ParsedItem<'a> {
+ let loc = s.iter().position(|&c| c == b'[').unwrap_or(s.len());
+ *index += loc;
+ ParsedItem {
+ item: FormatItem::Literal(&s[..loc]),
+ remaining: &s[loc..],
+ }
+}
+
+fn parse_item<'a>(
+ s: &'a [u8],
+ index: &mut usize,
+) -> Result<ParsedItem<'a>, InvalidFormatDescription> {
+ if let [b'[', b'[', remaining @ ..] = s {
+ *index += 2;
+ return Ok(ParsedItem {
+ item: FormatItem::Literal(b"["),
+ remaining,
+ });
+ };
+
+ if s.starts_with(b"[") {
+ if let Some(bracket_index) = s.iter().position(|&c| c == b']') {
+ *index += 1; // opening bracket
+ let ret_val = ParsedItem {
+ item: FormatItem::Component(parse_component(&s[1..bracket_index], index)?),
+ remaining: &s[bracket_index + 1..],
+ };
+ *index += 1; // closing bracket
+ Ok(ret_val)
+ } else {
+ Err(InvalidFormatDescription::UnclosedOpeningBracket { index: *index })
+ }
+ } else {
+ Ok(parse_literal(s, index))
+ }
+}
+
+pub(crate) fn parse(mut s: &[u8], span: Span) -> Result<Vec<FormatItem<'_>>, Error> {
+ let mut compound = Vec::new();
+ let mut loc = 0;
+
+ while !s.is_empty() {
+ let ParsedItem { item, remaining } =
+ parse_item(s, &mut loc).map_err(|error| Error::InvalidFormatDescription {
+ error,
+ span_start: Some(span),
+ span_end: Some(span),
+ })?;
+ s = remaining;
+ compound.push(item);
+ }
+
+ Ok(compound)
+}