Skip to content

Commit

Permalink
Merge pull request #664 from dtolnay-contrib/spannednew
Browse files Browse the repository at this point in the history
Add Spanned::new(Range<usize>, T)
  • Loading branch information
epage authored Dec 19, 2023
2 parents 42f4d56 + d2018b2 commit 60c4e9b
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 9 deletions.
40 changes: 31 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions crates/serde_spanned/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,9 @@ pre-release-replacements = [

[dependencies]
serde = { version = "1.0.145", optional = true }

[dev-dependencies]
serde = "1"
serde_derive = "1"
serde-untagged = "0.1"
toml = { path = "../toml" }
57 changes: 57 additions & 0 deletions crates/serde_spanned/src/spanned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,63 @@ pub struct Spanned<T> {
}

impl<T> Spanned<T> {
/// Create a spanned value encompassing the given byte range.
///
/// # Example
///
/// Transposing a `Spanned<Enum<T>>` into `Enum<Spanned<T>>`:
///
/// ```
/// use serde::de::{Deserialize, Deserializer};
/// use serde_untagged::UntaggedEnumVisitor;
/// use toml::Spanned;
///
/// pub enum Dependency {
/// Simple(Spanned<String>),
/// Detailed(Spanned<DetailedDependency>),
/// }
///
/// impl<'de> Deserialize<'de> for Dependency {
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
/// where
/// D: Deserializer<'de>,
/// {
/// enum DependencyKind {
/// Simple(String),
/// Detailed(DetailedDependency),
/// }
///
/// impl<'de> Deserialize<'de> for DependencyKind {
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
/// where
/// D: Deserializer<'de>,
/// {
/// UntaggedEnumVisitor::new()
/// .expecting(
/// "a version string like \"0.9.8\" or a \
/// detailed dependency like { version = \"0.9.8\" }",
/// )
/// .string(|value| Ok(DependencyKind::Simple(value.to_owned())))
/// .map(|value| value.deserialize().map(DependencyKind::Detailed))
/// .deserialize(deserializer)
/// }
/// }
///
/// let spanned: Spanned<DependencyKind> = Deserialize::deserialize(deserializer)?;
/// let range = spanned.span();
/// Ok(match spanned.into_inner() {
/// DependencyKind::Simple(simple) => Dependency::Simple(Spanned::new(range, simple)),
/// DependencyKind::Detailed(detailed) => Dependency::Detailed(Spanned::new(range, detailed)),
/// })
/// }
/// }
/// #
/// # type DetailedDependency = std::collections::BTreeMap<String, String>;
/// ```
pub fn new(range: std::ops::Range<usize>, value: T) -> Self {
Spanned { span: range, value }
}

/// Byte range
pub fn span(&self) -> std::ops::Range<usize> {
self.span.clone()
Expand Down

0 comments on commit 60c4e9b

Please sign in to comment.