diff --git a/src/array.rs b/src/array.rs index 0c1262e26..fd5ebe23b 100644 --- a/src/array.rs +++ b/src/array.rs @@ -340,7 +340,7 @@ impl IntoIterator for Array { self.values .into_iter() .filter(|v| v.is_value()) - .map(|v| v.into_value().unwrap()), + .map(|v| v.into_value()), ) } } diff --git a/src/de/item.rs b/src/de/item.rs index c8ba9b7b3..9f472791a 100644 --- a/src/de/item.rs +++ b/src/de/item.rs @@ -99,7 +99,6 @@ impl<'de, 'a> serde::Deserializer<'de> for crate::Item { V: serde::de::Visitor<'de>, { match self { - crate::Item::None => visitor.visit_none(), crate::Item::Value(v) => v.deserialize_any(visitor), crate::Item::Table(v) => visitor.visit_map(crate::de::TableMapAccess::new(v)), crate::Item::ArrayOfTables(v) => { diff --git a/src/index.rs b/src/index.rs index 276db7957..452494b38 100644 --- a/src/index.rs +++ b/src/index.rs @@ -1,9 +1,7 @@ use std::ops; use crate::document::Document; -use crate::key::Key; -use crate::table::TableKeyValue; -use crate::{value, InlineTable, InternalString, Item, Table, Value}; +use crate::{InlineTable, Item, Table, Value}; // copied from // https://github.com/serde-rs/json/blob/master/src/value/index.rs @@ -39,34 +37,16 @@ impl Index for str { Item::Value(ref v) => v .as_inline_table() .and_then(|t| t.items.get(self)) - .and_then(|kv| { - if !kv.value.is_none() { - Some(&kv.value) - } else { - None - } - }), + .map(|kv| &kv.value), _ => None, } } fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> { - if let Item::None = *v { - let mut t = InlineTable::default(); - t.items.insert( - InternalString::from(self), - TableKeyValue::new(Key::new(self), Item::None), - ); - *v = value(Value::InlineTable(t)); - } match *v { - Item::Table(ref mut t) => Some(t.entry(self).or_insert(Item::None)), - Item::Value(ref mut v) => v.as_inline_table_mut().map(|t| { - &mut t - .items - .entry(InternalString::from(self)) - .or_insert_with(|| TableKeyValue::new(Key::new(self), Item::None)) - .value - }), + Item::Table(ref mut t) => t.get_mut(self), + Item::Value(ref mut v) => v + .as_inline_table_mut() + .and_then(|t| t.items.get_mut(self).map(|kv| &mut kv.value)), _ => None, } } @@ -123,7 +103,7 @@ impl<'s> ops::Index<&'s str> for Table { impl<'s> ops::IndexMut<&'s str> for Table { fn index_mut(&mut self, key: &'s str) -> &mut Item { - self.entry(key).or_insert(Item::None) + self.get_mut(key).expect("index not found") } } diff --git a/src/inline_table.rs b/src/inline_table.rs index 1b8cf74b4..7cc453ebd 100644 --- a/src/inline_table.rs +++ b/src/inline_table.rs @@ -205,14 +205,8 @@ impl InlineTable { match self.items.entry(key.into()) { indexmap::map::Entry::Occupied(mut entry) => { // Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code. - let scratch = std::mem::take(&mut entry.get_mut().value); - let scratch = Item::Value( - scratch - .into_value() - // HACK: `Item::None` is a corner case of a corner case, let's just pick a - // "safe" value - .unwrap_or_else(|_| Value::InlineTable(Default::default())), - ); + let scratch = std::mem::replace(&mut entry.get_mut().value, crate::value(0)); + let scratch = Item::Value(scratch.into_value()); entry.get_mut().value = scratch; InlineEntry::Occupied(InlineOccupiedEntry { entry }) @@ -229,14 +223,8 @@ impl InlineTable { match self.items.entry(key.get().into()) { indexmap::map::Entry::Occupied(mut entry) => { // Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code. - let scratch = std::mem::take(&mut entry.get_mut().value); - let scratch = Item::Value( - scratch - .into_value() - // HACK: `Item::None` is a corner case of a corner case, let's just pick a - // "safe" value - .unwrap_or_else(|_| Value::InlineTable(Default::default())), - ); + let scratch = std::mem::replace(&mut entry.get_mut().value, crate::value(0)); + let scratch = Item::Value(scratch.into_value()); entry.get_mut().value = scratch; InlineEntry::Occupied(InlineOccupiedEntry { entry }) @@ -285,7 +273,7 @@ impl InlineTable { let kv = TableKeyValue::new(Key::new(key), Item::Value(value)); self.items .insert(InternalString::from(key), kv) - .and_then(|kv| kv.value.into_value().ok()) + .map(|kv| kv.value.into_value()) } /// Inserts a key-value pair into the map. @@ -294,21 +282,20 @@ impl InlineTable { self.items .insert(InternalString::from(key.get()), kv) .filter(|kv| kv.value.is_value()) - .map(|kv| kv.value.into_value().unwrap()) + .map(|kv| kv.value.into_value()) } /// Removes an item given the key. pub fn remove(&mut self, key: &str) -> Option { - self.items - .shift_remove(key) - .and_then(|kv| kv.value.into_value().ok()) + self.items.shift_remove(key).map(|kv| kv.value.into_value()) } /// Removes a key from the map, returning the stored key and value if the key was previously in the map. pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Value)> { - self.items.shift_remove(key).and_then(|kv| { + self.items.shift_remove(key).map(|kv| { let key = kv.key; - kv.value.into_value().ok().map(|value| (key, value)) + let value = kv.value.into_value(); + (key, value) }) } } @@ -351,7 +338,7 @@ impl IntoIterator for InlineTable { self.items .into_iter() .filter(|(_, kv)| kv.value.is_value()) - .map(|(k, kv)| (k, kv.value.into_value().unwrap())), + .map(|(k, kv)| (k, kv.value.into_value())), ) } } @@ -395,6 +382,12 @@ impl TableLike for InlineTable { .map(|(_, kv)| (kv.key.as_mut(), &mut kv.value)), ) } + fn len(&self) -> usize { + self.len() + } + fn is_empty(&self) -> bool { + self.is_empty() + } fn get<'s>(&'s self, key: &str) -> Option<&'s Item> { self.items.get(key).map(|kv| &kv.value) } @@ -405,8 +398,7 @@ impl TableLike for InlineTable { self.contains_key(key) } fn insert(&mut self, key: &str, value: Item) -> Option { - self.insert(key, value.into_value().unwrap()) - .map(Item::Value) + self.insert(key, value.into_value()).map(Item::Value) } fn remove(&mut self, key: &str) -> Option { self.remove(key).map(Item::Value) @@ -526,12 +518,12 @@ impl<'a> InlineOccupiedEntry<'a> { pub fn insert(&mut self, value: Value) -> Value { let mut value = Item::Value(value); std::mem::swap(&mut value, &mut self.entry.get_mut().value); - value.into_value().unwrap() + value.into_value() } /// Takes the value out of the entry, and returns it pub fn remove(self) -> Value { - self.entry.shift_remove().value.into_value().unwrap() + self.entry.shift_remove().value.into_value() } } diff --git a/src/item.rs b/src/item.rs index ac0601f1d..ae6cbda9d 100644 --- a/src/item.rs +++ b/src/item.rs @@ -8,8 +8,6 @@ use crate::{Array, InlineTable, Table, Value}; /// Type representing either a value, a table, an array of tables, or none. #[derive(Debug, Clone)] pub enum Item { - /// Type representing none. - None, /// Type representing value. Value(Value), /// Type representing table. @@ -18,24 +16,12 @@ pub enum Item { ArrayOfTables(ArrayOfTables), } -impl Item { - /// Sets `self` to the given item iff `self` is none and - /// returns a mutable reference to `self`. - pub fn or_insert(&mut self, item: Item) -> &mut Item { - if self.is_none() { - *self = item - } - self - } -} - // TODO: This should be generated by macro or derive /// Downcasting impl Item { /// Text description of value type pub fn type_name(&self) -> &'static str { match self { - Item::None => "none", Item::Value(v) => v.type_name(), Item::Table(..) => "table", Item::ArrayOfTables(..) => "array of tables", @@ -113,24 +99,23 @@ impl Item { } } /// Casts `self` to value. - pub fn into_value(self) -> Result { + pub fn into_value(self) -> Value { match self { - Item::None => Err(self), - Item::Value(v) => Ok(v), + Item::Value(v) => v, Item::Table(v) => { let v = v.into_inline_table(); - Ok(Value::InlineTable(v)) + Value::InlineTable(v) } Item::ArrayOfTables(v) => { let v = v.into_array(); - Ok(Value::Array(v)) + Value::Array(v) } } } /// In-place convert to a value pub fn make_value(&mut self) { - let other = std::mem::take(self); - let other = other.into_value().map(Item::Value).unwrap_or(Item::None); + let other = std::mem::replace(self, value(0)); + let other = Item::Value(other.into_value()); *self = other; } /// Casts `self` to table. @@ -164,7 +149,7 @@ impl Item { } // Starting private because the name is unclear pub(crate) fn make_item(&mut self) { - let other = std::mem::take(self); + let other = std::mem::replace(self, value(0)); let other = match other.into_table().map(crate::Item::Table) { Ok(i) => i, Err(i) => i, @@ -187,10 +172,6 @@ impl Item { pub fn is_array_of_tables(&self) -> bool { self.as_array_of_tables().is_some() } - /// Returns true iff `self` is `None`. - pub fn is_none(&self) -> bool { - matches!(*self, Item::None) - } // Duplicate Value downcasting API @@ -296,12 +277,6 @@ impl Item { } } -impl Default for Item { - fn default() -> Self { - Item::None - } -} - impl FromStr for Item { type Err = crate::TomlError; @@ -315,7 +290,6 @@ impl FromStr for Item { impl std::fmt::Display for Item { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self { - Item::None => Ok(()), Item::Value(v) => v.fmt(f), Item::Table(v) => v.fmt(f), Item::ArrayOfTables(v) => v.fmt(f), diff --git a/src/parser/table.rs b/src/parser/table.rs index 6c17df75d..53eba55af 100644 --- a/src/parser/table.rs +++ b/src/parser/table.rs @@ -113,7 +113,6 @@ impl TomlParser { Item::Table(ref mut sweet_child_of_mine) => { table = sweet_child_of_mine; } - _ => unreachable!(), } } Ok(table) diff --git a/src/ser/pretty.rs b/src/ser/pretty.rs index fe6cea9ac..5e14ab024 100644 --- a/src/ser/pretty.rs +++ b/src/ser/pretty.rs @@ -45,7 +45,6 @@ impl crate::visit_mut::VisitMut for Pretty { fn remove_table_prefix(node: &mut crate::Item) { match node { - crate::Item::None => {} crate::Item::Value(_) => {} crate::Item::Table(t) => t.decor_mut().set_prefix(""), crate::Item::ArrayOfTables(a) => { diff --git a/src/ser/table.rs b/src/ser/table.rs index 6cd5d5238..320c74b2b 100644 --- a/src/ser/table.rs +++ b/src/ser/table.rs @@ -1,4 +1,4 @@ -use super::{Error, ErrorKind, KeySerializer}; +use super::{Error, KeySerializer}; #[doc(hidden)] pub struct SerializeItemTable { @@ -111,17 +111,12 @@ impl serde::ser::SerializeMap for SerializeKeyValuePairs { let item = match res { Ok(item) => item, Err(e) => { - if e.kind != ErrorKind::UnsupportedNone { - return Err(e); - } - crate::Item::None + return Err(e); } }; - if !item.is_none() { - let key = self.key.take().unwrap(); - let kv = crate::table::TableKeyValue::new(crate::Key::new(&key), item); - self.items.insert(key, kv); - } + let key = self.key.take().unwrap(); + let kv = crate::table::TableKeyValue::new(crate::Key::new(&key), item); + self.items.insert(key, kv); Ok(()) } @@ -146,16 +141,11 @@ impl serde::ser::SerializeStruct for SerializeKeyValuePairs { let item = match res { Ok(item) => item, Err(e) => { - if e.kind != ErrorKind::UnsupportedNone { - return Err(e); - } - crate::Item::None + return Err(e); } }; - if !item.is_none() { - let kv = crate::table::TableKeyValue::new(crate::Key::new(key), item); - self.items.insert(crate::InternalString::from(key), kv); - } + let kv = crate::table::TableKeyValue::new(crate::Key::new(key), item); + self.items.insert(crate::InternalString::from(key), kv); Ok(()) } diff --git a/src/table.rs b/src/table.rs index 72e1c971b..a01c36c66 100644 --- a/src/table.rs +++ b/src/table.rs @@ -227,12 +227,7 @@ impl Table { impl Table { /// Returns an iterator over all key/value pairs, including empty. pub fn iter(&self) -> Iter<'_> { - Box::new( - self.items - .iter() - .filter(|(_, kv)| !kv.value.is_none()) - .map(|(key, kv)| (&key[..], &kv.value)), - ) + Box::new(self.items.iter().map(|(key, kv)| (&key[..], &kv.value))) } /// Returns an mutable iterator over all key/value pairs, including empty. @@ -240,19 +235,18 @@ impl Table { Box::new( self.items .iter_mut() - .filter(|(_, kv)| !kv.value.is_none()) .map(|(_, kv)| (kv.key.as_mut(), &mut kv.value)), ) } /// Returns the number of non-empty items in the table. pub fn len(&self) -> usize { - self.items.iter().filter(|i| !(i.1).value.is_none()).count() + self.items.len() } /// Returns true iff the table is empty. pub fn is_empty(&self) -> bool { - self.len() == 0 + self.items.is_empty() } /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse. @@ -283,33 +277,17 @@ impl Table { /// Returns an optional reference to an item given the key. pub fn get<'a>(&'a self, key: &str) -> Option<&'a Item> { - self.items.get(key).and_then(|kv| { - if !kv.value.is_none() { - Some(&kv.value) - } else { - None - } - }) + self.items.get(key).map(|kv| &kv.value) } /// Returns an optional mutable reference to an item given the key. pub fn get_mut<'a>(&'a mut self, key: &str) -> Option<&'a mut Item> { - self.items.get_mut(key).and_then(|kv| { - if !kv.value.is_none() { - Some(&mut kv.value) - } else { - None - } - }) + self.items.get_mut(key).map(|kv| &mut kv.value) } /// Returns true iff the table contains an item with the given key. pub fn contains_key(&self, key: &str) -> bool { - if let Some(kv) = self.items.get(key) { - !kv.value.is_none() - } else { - false - } + self.items.contains_key(key) } /// Returns true iff the table contains a table with the given key. @@ -462,13 +440,9 @@ pub trait TableLike: crate::private::Sealed { /// Returns an mutable iterator over all key/value pairs, including empty. fn iter_mut(&mut self) -> IterMut<'_>; /// Returns the number of nonempty items. - fn len(&self) -> usize { - self.iter().filter(|&(_, v)| !v.is_none()).count() - } + fn len(&self) -> usize; /// Returns true iff the table is empty. - fn is_empty(&self) -> bool { - self.len() == 0 - } + fn is_empty(&self) -> bool; /// Returns an optional reference to an item given the key. fn get<'s>(&'s self, key: &str) -> Option<&'s Item>; /// Returns an optional mutable reference to an item given the key. @@ -509,6 +483,12 @@ impl TableLike for Table { fn iter_mut(&mut self) -> IterMut<'_> { self.iter_mut() } + fn len(&self) -> usize { + self.len() + } + fn is_empty(&self) -> bool { + self.is_empty() + } fn get<'s>(&'s self, key: &str) -> Option<&'s Item> { self.get(key) } diff --git a/src/visit.rs b/src/visit.rs index 1bc640a88..9bf3bf325 100644 --- a/src/visit.rs +++ b/src/visit.rs @@ -28,7 +28,6 @@ //! V: Visit<'doc> + ?Sized, //! { //! match node { -//! Item::None => {} //! Item::Value(value) => v.visit_value(value), //! Item::Table(table) => v.visit_table(table), //! Item::ArrayOfTables(array) => v.visit_array_of_tables(array), @@ -149,7 +148,6 @@ where V: Visit<'doc> + ?Sized, { match node { - Item::None => {} Item::Value(value) => v.visit_value(value), Item::Table(table) => v.visit_table(table), Item::ArrayOfTables(array) => v.visit_array_of_tables(array), diff --git a/src/visit_mut.rs b/src/visit_mut.rs index 2c2af9752..192be2ad3 100644 --- a/src/visit_mut.rs +++ b/src/visit_mut.rs @@ -29,7 +29,6 @@ //! V: VisitMut + ?Sized, //! { //! match node { -//! Item::None => {} //! Item::Value(value) => v.visit_value_mut(value), //! Item::Table(table) => v.visit_table_mut(table), //! Item::ArrayOfTables(array) => v.visit_array_of_tables_mut(array), @@ -165,7 +164,6 @@ where V: VisitMut + ?Sized, { match node { - Item::None => {} Item::Value(value) => v.visit_value_mut(value), Item::Table(table) => v.visit_table_mut(table), Item::ArrayOfTables(array) => v.visit_array_of_tables_mut(array), diff --git a/tests/decoder.rs b/tests/decoder.rs index 9b60d9b00..1d5d2a2b7 100644 --- a/tests/decoder.rs +++ b/tests/decoder.rs @@ -24,7 +24,6 @@ fn item_to_decoded( value: &toml_edit::Item, ) -> Result { match value { - toml_edit::Item::None => unreachable!("No nones"), toml_edit::Item::Value(v) => value_to_decoded(v), toml_edit::Item::Table(v) => table_to_decoded(v), toml_edit::Item::ArrayOfTables(v) => { diff --git a/tests/test_valid.rs b/tests/test_valid.rs index 3cf0c0c3b..1a11a9262 100644 --- a/tests/test_valid.rs +++ b/tests/test_valid.rs @@ -37,7 +37,6 @@ fn pair_to_json((key, value): (&str, Item)) -> (String, Json) { .collect::>(), ), Item::Table(ref table) => to_json(iter_to_owned(table.iter())), - Item::None => Json::Null, }; (key.to_owned(), json) }