use std::str::FromStr;
use crate::array_of_tables::ArrayOfTables;
use crate::datetime::*;
use crate::table::TableLike;
use crate::{Array, InlineTable, Table, Value};
#[derive(Debug, Clone)]
pub enum Item {
None,
Value(Value),
Table(Table),
ArrayOfTables(ArrayOfTables),
}
impl Item {
pub fn or_insert(&mut self, item: Item) -> &mut Item {
if self.is_none() {
*self = item
}
self
}
}
impl Item {
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",
}
}
pub fn as_value(&self) -> Option<&Value> {
match *self {
Item::Value(ref v) => Some(v),
_ => None,
}
}
pub fn as_table(&self) -> Option<&Table> {
match *self {
Item::Table(ref t) => Some(t),
_ => None,
}
}
pub fn as_array_of_tables(&self) -> Option<&ArrayOfTables> {
match *self {
Item::ArrayOfTables(ref a) => Some(a),
_ => None,
}
}
pub fn as_value_mut(&mut self) -> Option<&mut Value> {
match *self {
Item::Value(ref mut v) => Some(v),
_ => None,
}
}
pub fn as_table_mut(&mut self) -> Option<&mut Table> {
match *self {
Item::Table(ref mut t) => Some(t),
_ => None,
}
}
pub fn as_array_of_tables_mut(&mut self) -> Option<&mut ArrayOfTables> {
match *self {
Item::ArrayOfTables(ref mut a) => Some(a),
_ => None,
}
}
pub fn into_value(self) -> Result<Value, Self> {
match self {
Item::None => Err(self),
Item::Value(v) => Ok(v),
Item::Table(v) => Ok(Value::InlineTable(v.into_inline_table())),
Item::ArrayOfTables(v) => Ok(Value::Array(v.into_array())),
}
}
pub fn make_value(&mut self) {
let mut other = Item::None;
std::mem::swap(self, &mut other);
let mut other = other.into_value().map(Item::Value).unwrap_or(Item::None);
std::mem::swap(self, &mut other);
}
pub fn into_table(self) -> Result<Table, Self> {
match self {
Item::Table(t) => Ok(t),
_ => Err(self),
}
}
pub fn into_array_of_tables(self) -> Result<ArrayOfTables, Self> {
match self {
Item::ArrayOfTables(a) => Ok(a),
_ => Err(self),
}
}
pub fn is_value(&self) -> bool {
self.as_value().is_some()
}
pub fn is_table(&self) -> bool {
self.as_table().is_some()
}
pub fn is_array_of_tables(&self) -> bool {
self.as_array_of_tables().is_some()
}
pub fn is_none(&self) -> bool {
matches!(*self, Item::None)
}
pub fn as_integer(&self) -> Option<i64> {
self.as_value().and_then(Value::as_integer)
}
pub fn is_integer(&self) -> bool {
self.as_integer().is_some()
}
pub fn as_float(&self) -> Option<f64> {
self.as_value().and_then(Value::as_float)
}
pub fn is_float(&self) -> bool {
self.as_float().is_some()
}
pub fn as_bool(&self) -> Option<bool> {
self.as_value().and_then(Value::as_bool)
}
pub fn is_bool(&self) -> bool {
self.as_bool().is_some()
}
pub fn as_str(&self) -> Option<&str> {
self.as_value().and_then(Value::as_str)
}
pub fn is_str(&self) -> bool {
self.as_str().is_some()
}
pub fn as_datetime(&self) -> Option<&Datetime> {
self.as_value().and_then(Value::as_datetime)
}
pub fn is_datetime(&self) -> bool {
self.as_datetime().is_some()
}
pub fn as_array(&self) -> Option<&Array> {
self.as_value().and_then(Value::as_array)
}
pub fn as_array_mut(&mut self) -> Option<&mut Array> {
self.as_value_mut().and_then(Value::as_array_mut)
}
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
pub fn as_inline_table(&self) -> Option<&InlineTable> {
self.as_value().and_then(Value::as_inline_table)
}
pub fn as_inline_table_mut(&mut self) -> Option<&mut InlineTable> {
self.as_value_mut().and_then(Value::as_inline_table_mut)
}
pub fn is_inline_table(&self) -> bool {
self.as_inline_table().is_some()
}
pub fn as_table_like(&self) -> Option<&dyn TableLike> {
self.as_table()
.map(|t| t as &dyn TableLike)
.or_else(|| self.as_inline_table().map(|t| t as &dyn TableLike))
}
pub fn as_table_like_mut(&mut self) -> Option<&mut dyn TableLike> {
match self {
Item::Table(t) => Some(t as &mut dyn TableLike),
Item::Value(Value::InlineTable(t)) => Some(t as &mut dyn TableLike),
_ => None,
}
}
pub fn is_table_like(&self) -> bool {
self.as_table_like().is_some()
}
}
impl Default for Item {
fn default() -> Self {
Item::None
}
}
impl FromStr for Item {
type Err = crate::TomlError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let value = s.parse::<Value>()?;
Ok(Item::Value(value))
}
}
pub fn value<V: Into<Value>>(v: V) -> Item {
Item::Value(v.into().decorated(" ", ""))
}
pub fn table() -> Item {
Item::Table(Table::new())
}
pub fn array() -> Item {
Item::ArrayOfTables(ArrayOfTables::new())
}