Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(edit)!: Allow disabling parser or display #648

Merged
merged 4 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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