diff options
Diffstat (limited to 'vendor/toml_edit/src/raw_string.rs')
-rw-r--r-- | vendor/toml_edit/src/raw_string.rs | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/vendor/toml_edit/src/raw_string.rs b/vendor/toml_edit/src/raw_string.rs new file mode 100644 index 0000000..c5961f1 --- /dev/null +++ b/vendor/toml_edit/src/raw_string.rs @@ -0,0 +1,182 @@ +use crate::InternalString; + +/// Opaque string storage for raw TOML; internal to `toml_edit` +#[derive(PartialEq, Eq, Clone, Hash)] +pub struct RawString(RawStringInner); + +#[derive(PartialEq, Eq, Clone, Hash)] +enum RawStringInner { + Empty, + Explicit(InternalString), + Spanned(std::ops::Range<usize>), +} + +impl RawString { + pub(crate) fn with_span(span: std::ops::Range<usize>) -> Self { + if span.start == span.end { + RawString(RawStringInner::Empty) + } else { + RawString(RawStringInner::Spanned(span)) + } + } + + /// Access the underlying string + pub fn as_str(&self) -> Option<&str> { + match &self.0 { + RawStringInner::Empty => Some(""), + RawStringInner::Explicit(s) => Some(s.as_str()), + RawStringInner::Spanned(_) => None, + } + } + + pub(crate) fn to_str<'s>(&'s self, input: &'s str) -> &'s str { + match &self.0 { + RawStringInner::Empty => "", + RawStringInner::Explicit(s) => s.as_str(), + RawStringInner::Spanned(span) => input.get(span.clone()).unwrap_or_else(|| { + panic!("span {:?} should be in input:\n```\n{}\n```", span, input) + }), + } + } + + pub(crate) fn to_str_with_default<'s>( + &'s self, + input: Option<&'s str>, + default: &'s str, + ) -> &'s str { + match &self.0 { + RawStringInner::Empty => "", + RawStringInner::Explicit(s) => s.as_str(), + RawStringInner::Spanned(span) => { + if let Some(input) = input { + input.get(span.clone()).unwrap_or_else(|| { + panic!("span {:?} should be in input:\n```\n{}\n```", span, input) + }) + } else { + default + } + } + } + } + + /// Access the underlying span + pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { + match &self.0 { + RawStringInner::Empty => None, + RawStringInner::Explicit(_) => None, + RawStringInner::Spanned(span) => Some(span.clone()), + } + } + + pub(crate) fn despan(&mut self, input: &str) { + match &self.0 { + RawStringInner::Empty => {} + RawStringInner::Explicit(_) => {} + RawStringInner::Spanned(span) => { + *self = Self::from(input.get(span.clone()).unwrap_or_else(|| { + panic!("span {:?} should be in input:\n```\n{}\n```", span, input) + })) + } + } + } + + pub(crate) fn encode(&self, buf: &mut dyn std::fmt::Write, input: &str) -> std::fmt::Result { + let raw = self.to_str(input); + for part in raw.split('\r') { + write!(buf, "{}", part)?; + } + Ok(()) + } + + pub(crate) fn encode_with_default( + &self, + buf: &mut dyn std::fmt::Write, + input: Option<&str>, + default: &str, + ) -> std::fmt::Result { + let raw = self.to_str_with_default(input, default); + for part in raw.split('\r') { + write!(buf, "{}", part)?; + } + Ok(()) + } +} + +impl Default for RawString { + fn default() -> Self { + Self(RawStringInner::Empty) + } +} + +impl std::fmt::Debug for RawString { + #[inline] + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + match &self.0 { + RawStringInner::Empty => write!(formatter, "empty"), + RawStringInner::Explicit(s) => write!(formatter, "{:?}", s), + RawStringInner::Spanned(s) => write!(formatter, "{:?}", s), + } + } +} + +impl From<&str> for RawString { + #[inline] + fn from(s: &str) -> Self { + if s.is_empty() { + Self(RawStringInner::Empty) + } else { + InternalString::from(s).into() + } + } +} + +impl From<String> for RawString { + #[inline] + fn from(s: String) -> Self { + if s.is_empty() { + Self(RawStringInner::Empty) + } else { + InternalString::from(s).into() + } + } +} + +impl From<&String> for RawString { + #[inline] + fn from(s: &String) -> Self { + if s.is_empty() { + Self(RawStringInner::Empty) + } else { + InternalString::from(s).into() + } + } +} + +impl From<InternalString> for RawString { + #[inline] + fn from(inner: InternalString) -> Self { + Self(RawStringInner::Explicit(inner)) + } +} + +impl From<&InternalString> for RawString { + #[inline] + fn from(s: &InternalString) -> Self { + if s.is_empty() { + Self(RawStringInner::Empty) + } else { + InternalString::from(s).into() + } + } +} + +impl From<Box<str>> for RawString { + #[inline] + fn from(s: Box<str>) -> Self { + if s.is_empty() { + Self(RawStringInner::Empty) + } else { + InternalString::from(s).into() + } + } +} |