Skip to content

Commit

Permalink
Merge pull request #648 from epage/split
Browse files Browse the repository at this point in the history
fix(edit)!: Allow disabling parser or display
  • Loading branch information
epage committed Nov 6, 2023
2 parents 6c8885e + ef9fd0a commit 7ba0932
Show file tree
Hide file tree
Showing 30 changed files with 255 additions and 108 deletions.
4 changes: 2 additions & 2 deletions crates/toml/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ pre-release-replacements = [

[features]
default = ["parse", "display"]
parse = ["dep:toml_edit"]
display = ["dep:toml_edit"]
parse = ["dep:toml_edit", "toml_edit?/parse"]
display = ["dep:toml_edit", "toml_edit?/display"]

# Use indexmap rather than BTreeMap as the map type of toml::Value.
# This allows data to be read into a Value and written back to a TOML string
Expand Down
15 changes: 13 additions & 2 deletions crates/toml_edit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ keywords = ["encoding", "toml"]
categories = ["encoding", "parser-implementations", "parsing", "config"]
description = "Yet another format-preserving TOML parser."
authors = ["Andronik Ordian <write@reusable.software>", "Ed Page <eopage@gmail.com>"]
autotests = false
repository.workspace = true
license.workspace = true
edition.workspace = true
Expand All @@ -26,7 +27,9 @@ pre-release-replacements = [
]

[features]
default = []
default = ["parse", "display"]
parse = ["dep:winnow"]
display = []
perf = ["dep:kstring"]
serde = ["dep:serde", "toml_datetime/serde", "dep:serde_spanned"]
# Provide a method disable_recursion_limit to parse arbitrarily deep structures
Expand All @@ -38,7 +41,7 @@ unbounded = []

[dependencies]
indexmap = { version = "2.0.0", features = ["std"] }
winnow = "0.5.0"
winnow = { version = "0.5.0", optional = true }
serde = { version = "1.0.145", optional = true }
kstring = { version = "2.0.0", features = ["max_inline"], optional = true }
toml_datetime = { version = "0.6.5", path = "../toml_datetime" }
Expand All @@ -51,18 +54,26 @@ toml-test-data = "1.4.0"
libtest-mimic = "0.6.0"
snapbox = { version = "0.4.11", features = ["harness"] }

[[test]]
name = "testsuite"
required-features = ["parse", "display"]

[[test]]
name = "decoder_compliance"
required-features = ["parse"]
harness = false

[[test]]
name = "encoder_compliance"
required-features = ["parse", "display"]
harness = false

[[test]]
name = "invalid"
required-features = ["parse"]
harness = false

[[example]]
name = "visit"
required-features = ["parse", "display"]
test = true
7 changes: 7 additions & 0 deletions crates/toml_edit/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,11 @@ impl Array {
/// # Examples
///
/// ```rust
/// # #[cfg(feature = "parse")] {
/// let formatted_value = "'literal'".parse::<toml_edit::Value>().unwrap();
/// let mut arr = toml_edit::Array::new();
/// arr.push_formatted(formatted_value);
/// # }
/// ```
pub fn push_formatted(&mut self, v: Value) {
self.values.push(Item::Value(v));
Expand Down Expand Up @@ -223,12 +225,14 @@ impl Array {
/// # Examples
///
/// ```rust
/// # #[cfg(feature = "parse")] {
/// let mut arr = toml_edit::Array::new();
/// arr.push(1);
/// arr.push("foo");
///
/// let formatted_value = "'start'".parse::<toml_edit::Value>().unwrap();
/// arr.insert_formatted(0, formatted_value);
/// # }
/// ```
pub fn insert_formatted(&mut self, index: usize, v: Value) {
self.values.insert(index, Item::Value(v))
Expand Down Expand Up @@ -269,12 +273,14 @@ impl Array {
/// # Examples
///
/// ```rust
/// # #[cfg(feature = "parse")] {
/// let mut arr = toml_edit::Array::new();
/// arr.push(1);
/// arr.push("foo");
///
/// let formatted_value = "'start'".parse::<toml_edit::Value>().unwrap();
/// arr.replace_formatted(0, formatted_value);
/// # }
/// ```
pub fn replace_formatted(&mut self, index: usize, v: Value) -> Value {
match mem::replace(&mut self.values[index], Item::Value(v)) {
Expand Down Expand Up @@ -383,6 +389,7 @@ impl Array {
}
}

#[cfg(feature = "display")]
impl std::fmt::Display for Array {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
crate::encode::Encode::encode(self, f, None, ("", ""))
Expand Down
1 change: 1 addition & 0 deletions crates/toml_edit/src/array_of_tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ impl<'s> IntoIterator for &'s ArrayOfTables {
}
}

#[cfg(feature = "display")]
impl std::fmt::Display for ArrayOfTables {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// HACK: Without the header, we don't really have a proper way of printing this
Expand Down
3 changes: 3 additions & 0 deletions crates/toml_edit/src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ impl From<Error> for crate::TomlError {
impl std::error::Error for Error {}

/// Convert a value into `T`.
#[cfg(feature = "parse")]
pub fn from_str<T>(s: &'_ str) -> Result<T, Error>
where
T: DeserializeOwned,
Expand All @@ -96,6 +97,7 @@ where
}

/// Convert a value into `T`.
#[cfg(feature = "parse")]
pub fn from_slice<T>(s: &'_ [u8]) -> Result<T, Error>
where
T: DeserializeOwned,
Expand Down Expand Up @@ -125,6 +127,7 @@ impl Deserializer {
}
}

#[cfg(feature = "parse")]
impl std::str::FromStr for Deserializer {
type Err = Error;

Expand Down
1 change: 1 addition & 0 deletions crates/toml_edit/src/de/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ impl crate::Item {
}
}

#[cfg(feature = "parse")]
impl std::str::FromStr for ValueDeserializer {
type Err = Error;

Expand Down
4 changes: 2 additions & 2 deletions crates/toml_edit/src/document.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::str::FromStr;

use crate::parser;
use crate::table::Iter;
use crate::{Item, RawString, Table};

Expand Down Expand Up @@ -78,12 +77,13 @@ impl Default for Document {
}
}

#[cfg(feature = "parse")]
impl FromStr for Document {
type Err = crate::TomlError;

/// Parses a document from a &str
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut d = parser::parse_document(s)?;
let mut d = crate::parser::parse_document(s)?;
d.despan();
Ok(d)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
use std::error::Error as StdError;
use std::fmt::{Display, Formatter, Result};

use crate::parser::prelude::*;
use crate::Key;

use winnow::error::ContextError;
use winnow::error::ParseError;

/// Type representing a TOML parse error
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct TomlError {
Expand All @@ -17,7 +11,14 @@ pub struct TomlError {
}

impl TomlError {
pub(crate) fn new(error: ParseError<Input<'_>, ContextError>, mut original: Input<'_>) -> Self {
#[cfg(feature = "parse")]
pub(crate) fn new(
error: winnow::error::ParseError<
crate::parser::prelude::Input<'_>,
winnow::error::ContextError,
>,
mut original: crate::parser::prelude::Input<'_>,
) -> Self {
use winnow::stream::Stream;

let offset = error.offset();
Expand Down Expand Up @@ -243,73 +244,3 @@ mod test_translate_position {
assert_eq!(position, (1, 2));
}
}

#[derive(Debug, Clone)]
pub(crate) enum CustomError {
DuplicateKey {
key: String,
table: Option<Vec<Key>>,
},
DottedKeyExtendWrongType {
key: Vec<Key>,
actual: &'static str,
},
OutOfRange,
#[cfg_attr(feature = "unbounded", allow(dead_code))]
RecursionLimitExceeded,
}

impl CustomError {
pub(crate) fn duplicate_key(path: &[Key], i: usize) -> Self {
assert!(i < path.len());
let key = &path[i];
let repr = key.display_repr();
Self::DuplicateKey {
key: repr.into(),
table: Some(path[..i].to_vec()),
}
}

pub(crate) fn extend_wrong_type(path: &[Key], i: usize, actual: &'static str) -> Self {
assert!(i < path.len());
Self::DottedKeyExtendWrongType {
key: path[..=i].to_vec(),
actual,
}
}
}

impl StdError for CustomError {
fn description(&self) -> &'static str {
"TOML parse error"
}
}

impl Display for CustomError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
match self {
CustomError::DuplicateKey { key, table } => {
if let Some(table) = table {
if table.is_empty() {
write!(f, "duplicate key `{}` in document root", key)
} else {
let path = table.iter().map(|k| k.get()).collect::<Vec<_>>().join(".");
write!(f, "duplicate key `{}` in table `{}`", key, path)
}
} else {
write!(f, "duplicate key `{}`", key)
}
}
CustomError::DottedKeyExtendWrongType { key, actual } => {
let path = key.iter().map(|k| k.get()).collect::<Vec<_>>().join(".");
write!(
f,
"dotted key `{}` attempted to extend non-table type ({})",
path, actual
)
}
CustomError::OutOfRange => write!(f, "value is out of range"),
CustomError::RecursionLimitExceeded => write!(f, "recursion limit exceeded"),
}
}
}
5 changes: 5 additions & 0 deletions crates/toml_edit/src/inline_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,15 @@ impl InlineTable {
/// In the document above, tables `target` and `target."x86_64/windows.json"` are implicit.
///
/// ```
/// # #[cfg(feature = "parse")] {
/// # #[cfg(feature = "display")] {
/// use toml_edit::Document;
/// let mut doc = "[a]\n[a.b]\n".parse::<Document>().expect("invalid toml");
///
/// doc["a"].as_table_mut().unwrap().set_implicit(true);
/// assert_eq!(doc.to_string(), "[a.b]\n");
/// # }
/// # }
/// ```
pub(crate) fn set_implicit(&mut self, implicit: bool) {
self.implicit = implicit;
Expand Down Expand Up @@ -411,6 +415,7 @@ impl InlineTable {
}
}

#[cfg(feature = "display")]
impl std::fmt::Display for InlineTable {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
crate::encode::Encode::encode(self, f, None, ("", ""))
Expand Down
4 changes: 4 additions & 0 deletions crates/toml_edit/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ impl Clone for Item {
}
}

#[cfg(feature = "parse")]
impl FromStr for Item {
type Err = crate::TomlError;

Expand All @@ -339,6 +340,7 @@ impl FromStr for Item {
}
}

#[cfg(feature = "display")]
impl std::fmt::Display for Item {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self {
Expand All @@ -358,6 +360,7 @@ impl std::fmt::Display for Item {
///
/// # Examples
/// ```rust
/// # #[cfg(feature = "display")] {
/// # use snapbox::assert_eq;
/// # use toml_edit::*;
/// let mut table = Table::default();
Expand All @@ -372,6 +375,7 @@ impl std::fmt::Display for Item {
/// key2 = 42
/// key3 = ["hello", '\, world']
/// "#);
/// # }
/// ```
pub fn value<V: Into<Value>>(v: V) -> Item {
Item::Value(v.into())
Expand Down
Loading

0 comments on commit 7ba0932

Please sign in to comment.