|
@@ -0,0 +1,827 @@
|
|
|
+use std::{collections::HashMap, fmt::Display, slice::{SliceIndex, Iter, IterMut}};
|
|
|
+
|
|
|
+#[cfg(feature = "shared")]
|
|
|
+use crate::Shared;
|
|
|
+
|
|
|
+#[cfg(not(feature = "serde"))]
|
|
|
+#[derive(Debug, PartialEq, Clone)]
|
|
|
+pub enum Data {
|
|
|
+ None,
|
|
|
+ String(String),
|
|
|
+ I8(i8),
|
|
|
+ I16(i16),
|
|
|
+ I32(i32),
|
|
|
+ I64(i64),
|
|
|
+ I128(i128),
|
|
|
+ U8(u8),
|
|
|
+ U16(u16),
|
|
|
+ U32(u32),
|
|
|
+ U64(u64),
|
|
|
+ U128(u128),
|
|
|
+ F32(f32),
|
|
|
+ F64(f64),
|
|
|
+ Bool(bool),
|
|
|
+ Vec(Vec<Data>),
|
|
|
+ Map(HashMap<String, Data>),
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature="serde")]
|
|
|
+#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
|
|
|
+pub enum Data {
|
|
|
+ None,
|
|
|
+ String(String),
|
|
|
+ I8(i8),
|
|
|
+ I16(i16),
|
|
|
+ I32(i32),
|
|
|
+ I64(i64),
|
|
|
+ I128(i128),
|
|
|
+ U8(u8),
|
|
|
+ U16(u16),
|
|
|
+ U32(u32),
|
|
|
+ U64(u64),
|
|
|
+ U128(u128),
|
|
|
+ F32(f32),
|
|
|
+ F64(f64),
|
|
|
+ Bool(bool),
|
|
|
+ Vec(Vec<Data>),
|
|
|
+ Map(HashMap<String, Data>),
|
|
|
+}
|
|
|
+
|
|
|
+impl Default for Data {
|
|
|
+ fn default() -> Self {
|
|
|
+ Self::None
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Display for Data {
|
|
|
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
+ match self {
|
|
|
+ Self::None => f.write_str("None"),
|
|
|
+ Self::String(s) => f.write_str(s),
|
|
|
+ Self::I8(i) => f.write_str(format!("{}", i).as_str()),
|
|
|
+ Self::I16(i) => f.write_str(format!("{}", i).as_str()),
|
|
|
+ Self::I32(i) => f.write_str(format!("{}", i).as_str()),
|
|
|
+ Self::I64(i) => f.write_str(format!("{}", i).as_str()),
|
|
|
+ Self::I128(i) => f.write_str(format!("{}", i).as_str()),
|
|
|
+ Self::U8(i) => f.write_str(format!("{}", i).as_str()),
|
|
|
+ Self::U16(i) => f.write_str(format!("{}", i).as_str()),
|
|
|
+ Self::U32(i) => f.write_str(format!("{}", i).as_str()),
|
|
|
+ Self::U64(i) => f.write_str(format!("{}", i).as_str()),
|
|
|
+ Self::U128(i) => f.write_str(format!("{}", i).as_str()),
|
|
|
+ Self::F32(v) => f.write_str(format!("{}", v).as_str()),
|
|
|
+ Self::F64(v) => f.write_str(format!("{}", v).as_str()),
|
|
|
+ Self::Bool(b) => f.write_str(format!("{}", b).as_str()),
|
|
|
+ Self::Vec(v) => {
|
|
|
+ let mut out: String = "[".to_string();
|
|
|
+ for d in v.iter() {
|
|
|
+ if out != "[" {
|
|
|
+ out.push_str(", ");
|
|
|
+ }
|
|
|
+ out.push_str(format!("{}", d).as_str());
|
|
|
+ }
|
|
|
+ out.push(']');
|
|
|
+ f.write_str(out.as_str())
|
|
|
+ },
|
|
|
+ Self::Map(hm) => {
|
|
|
+ let mut out: String = "{".to_string();
|
|
|
+ for (k, v) in hm.iter() {
|
|
|
+ if out != "{" {
|
|
|
+ out.push_str(", ");
|
|
|
+ }
|
|
|
+ out.push_str(format!("{}: {}", k, v).as_str());
|
|
|
+ }
|
|
|
+ out.push('}');
|
|
|
+ f.write_str(out.as_str())
|
|
|
+ },
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<String> for Data {
|
|
|
+ fn from(value: String) -> Self {
|
|
|
+ Self::String(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<i8> for Data {
|
|
|
+ fn from(value: i8) -> Self {
|
|
|
+ Self::I8(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<i16> for Data {
|
|
|
+ fn from(value: i16) -> Self {
|
|
|
+ Self::I16(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<i32> for Data {
|
|
|
+ fn from(value: i32) -> Self {
|
|
|
+ Self::I32(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<i64> for Data {
|
|
|
+ fn from(value: i64) -> Self {
|
|
|
+ Self::I64(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<i128> for Data {
|
|
|
+ fn from(value: i128) -> Self {
|
|
|
+ Self::I128(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<u8> for Data {
|
|
|
+ fn from(value: u8) -> Self {
|
|
|
+ Self::U8(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<u16> for Data {
|
|
|
+ fn from(value: u16) -> Self {
|
|
|
+ Self::U16(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<u32> for Data {
|
|
|
+ fn from(value: u32) -> Self {
|
|
|
+ Self::U32(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<u64> for Data {
|
|
|
+ fn from(value: u64) -> Self {
|
|
|
+ Self::U64(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<u128> for Data {
|
|
|
+ fn from(value: u128) -> Self {
|
|
|
+ Self::U128(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<f32> for Data {
|
|
|
+ fn from(value: f32) -> Self {
|
|
|
+ Self::F32(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<f64> for Data {
|
|
|
+ fn from(value: f64) -> Self {
|
|
|
+ Self::F64(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<bool> for Data {
|
|
|
+ fn from(value: bool) -> Self {
|
|
|
+ Self::Bool(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<Vec<Data>> for Data {
|
|
|
+ fn from(value: Vec<Data>) -> Self {
|
|
|
+ Self::Vec(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<HashMap<String, Data>> for Data {
|
|
|
+ fn from(value: HashMap<String, Data>) -> Self {
|
|
|
+ Self::Map(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(not(feature = "cast_into"))]
|
|
|
+impl TryInto<String> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<String, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::String(s) => Ok(s),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature = "cast_into")]
|
|
|
+impl TryInto<String> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<String, Self::Error> {
|
|
|
+ Ok(format!("{}", self)) // Reuse Display trait
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// i8 is the smallest bit variant... so no cast_into feature
|
|
|
+impl TryInto<i8> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<i8, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::I8(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(not(feature = "cast_into"))]
|
|
|
+impl TryInto<i16> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<i16, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::I16(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature = "cast_into")]
|
|
|
+impl TryInto<i16> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<i16, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::I8(v) => Ok(v as i16), // bump up
|
|
|
+ Self::I16(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(not(feature = "cast_into"))]
|
|
|
+impl TryInto<i32> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<i32, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::I32(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature = "cast_into")]
|
|
|
+impl TryInto<i32> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<i32, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::I8(v) => Ok(v as i32), // bump up
|
|
|
+ Self::I16(v) => Ok(v as i32), // bump up
|
|
|
+ Self::I32(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(not(feature = "cast_into"))]
|
|
|
+impl TryInto<i64> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<i64, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::I64(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature = "cast_into")]
|
|
|
+impl TryInto<i64> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<i64, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::I8(v) => Ok(v as i64), // bump up
|
|
|
+ Self::I16(v) => Ok(v as i64), // bump up
|
|
|
+ Self::I32(v) => Ok(v as i64), // bump up
|
|
|
+ Self::I64(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(not(feature = "cast_into"))]
|
|
|
+impl TryInto<i128> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<i128, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::I128(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature = "cast_into")]
|
|
|
+impl TryInto<i128> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<i128, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::I8(v) => Ok(v as i128), // bump up
|
|
|
+ Self::I16(v) => Ok(v as i128), // bump up
|
|
|
+ Self::I32(v) => Ok(v as i128), // bump up
|
|
|
+ Self::I64(v) => Ok(v as i128), // bump up
|
|
|
+ Self::I128(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// u8 is the smallest bit variant, so no cast_into
|
|
|
+impl TryInto<u8> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<u8, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::U8(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(not(feature = "cast_into"))]
|
|
|
+impl TryInto<u16> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<u16, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::U16(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature = "cast_into")]
|
|
|
+impl TryInto<u16> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<u16, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::U8(v) => Ok(v as u16), // bump up
|
|
|
+ Self::U16(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(not(feature = "cast_into"))]
|
|
|
+impl TryInto<u32> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<u32, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::U32(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature = "cast_into")]
|
|
|
+impl TryInto<u32> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<u32, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::U8(v) => Ok(v as u32), // bump up
|
|
|
+ Self::U16(v) => Ok(v as u32), // bump up
|
|
|
+ Self::U32(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(not(feature = "cast_into"))]
|
|
|
+impl TryInto<u64> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<u64, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::U64(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature = "cast_into")]
|
|
|
+impl TryInto<u64> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<u64, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::U8(v) => Ok(v as u64), // bump up
|
|
|
+ Self::U16(v) => Ok(v as u64), // bump up
|
|
|
+ Self::U32(v) => Ok(v as u64), // bump up
|
|
|
+ Self::U64(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(not(feature = "cast_into"))]
|
|
|
+impl TryInto<u128> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<u128, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::U128(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature = "cast_into")]
|
|
|
+impl TryInto<u128> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<u128, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::U8(v) => Ok(v as u128), // bump up
|
|
|
+ Self::U16(v) => Ok(v as u128), // bump up
|
|
|
+ Self::U32(v) => Ok(v as u128), // bump up
|
|
|
+ Self::U64(v) => Ok(v as u128), // bump up
|
|
|
+ Self::U128(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// because float only has 32 or 64, f32 will have no cast_into
|
|
|
+impl TryInto<f32> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<f32, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::F32(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(not(feature = "cast_into"))]
|
|
|
+impl TryInto<f64> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<f64, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::F64(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature = "cast_into")]
|
|
|
+impl TryInto<f64> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<f64, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::F32(v) => Ok(v as f64), // bump up
|
|
|
+ Self::F64(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(not(feature = "cast_into"))]
|
|
|
+impl TryInto<bool> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<bool, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::Bool(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#[cfg(feature = "cast_into")]
|
|
|
+impl TryInto<bool> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<bool, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::String(s) => Ok(!s.is_empty()),
|
|
|
+ Self::I8(v) => Ok(v != 0),
|
|
|
+ Self::I16(v) => Ok(v != 0),
|
|
|
+ Self::I32(v) => Ok(v != 0),
|
|
|
+ Self::I64(v) => Ok(v != 0),
|
|
|
+ Self::I128(v) => Ok(v != 0),
|
|
|
+ Self::U8(v) => Ok(v != 0),
|
|
|
+ Self::U16(v) => Ok(v != 0),
|
|
|
+ Self::U32(v) => Ok(v != 0),
|
|
|
+ Self::U64(v) => Ok(v != 0),
|
|
|
+ Self::U128(v) => Ok(v != 0),
|
|
|
+ Self::F32(v) => Ok(v != 0.0),
|
|
|
+ Self::F64(v) => Ok(v != 0.0),
|
|
|
+ Self::Bool(b) => Ok(b),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// cast_into doesn't make sense here
|
|
|
+impl TryInto<Vec<Data>> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<Vec<Data>, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// cast_into doesn't make sense here
|
|
|
+impl TryInto<HashMap<String, Data>> for Data {
|
|
|
+ type Error = ();
|
|
|
+ fn try_into(self) -> Result<HashMap<String, Data>, Self::Error> {
|
|
|
+ match self {
|
|
|
+ Self::Map(v) => Ok(v),
|
|
|
+ _ => Err(()),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// To cast Data into `Shared<Data>`
|
|
|
+// (Because we're still in the crate, we can do this)
|
|
|
+#[cfg(feature = "shared")]
|
|
|
+impl From<Data> for Shared<Data> {
|
|
|
+ fn from(v: Data) -> Self {
|
|
|
+ Shared::new(v)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Data {
|
|
|
+ /// Constructs a new empty Vec of `Vec<Data>`
|
|
|
+ pub fn new_vec() -> Self {
|
|
|
+ Self::Vec(Vec::new())
|
|
|
+ }
|
|
|
+ /// Constructs a new empty Map of `HashMap<String, Data>`
|
|
|
+ pub fn new_map() -> Self {
|
|
|
+ Self::Map(HashMap::new())
|
|
|
+ }
|
|
|
+ /// Constructs a new Vec with capacity
|
|
|
+ pub fn vec_with_capacity(cap: usize) -> Self {
|
|
|
+ Self::Vec(Vec::with_capacity(cap))
|
|
|
+ }
|
|
|
+ /// Constructs a new Map with capacity
|
|
|
+ pub fn map_with_capacity(cap: usize) -> Self {
|
|
|
+ Self::Map(HashMap::with_capacity(cap))
|
|
|
+ }
|
|
|
+ /// Is Data not the variant None
|
|
|
+ ///
|
|
|
+ /// This is useful for using Data similar to a Option
|
|
|
+ pub fn is_some(&self) -> bool {
|
|
|
+ !matches!(self, Self::None)
|
|
|
+ }
|
|
|
+ /// Is Data the variant None
|
|
|
+ pub fn is_none(&self) -> bool {
|
|
|
+ matches!(self, Self::None)
|
|
|
+ }
|
|
|
+ /// Is Data a String
|
|
|
+ pub fn is_string(&self) -> bool {
|
|
|
+ matches!(self, Self::String(_))
|
|
|
+ }
|
|
|
+ /// Is Data a signed/unsigned integer or float
|
|
|
+ ///
|
|
|
+ /// JSON Number's can hold both a whole number (i.e. signed/unsigned integers) and floats
|
|
|
+ pub fn is_number(&self) -> bool {
|
|
|
+ matches!(self, Self::I8(_) | Self::I16(_) | Self::I32(_) | Self::I64(_) | Self::I128(_) | Self::U8(_) | Self::U16(_) | Self::U32(_) | Self::U64(_) | Self::U128(_) | Self::F32(_) | Self::F64(_))
|
|
|
+ }
|
|
|
+ /// Is Data a signed integer (Regardless of bits)
|
|
|
+ ///
|
|
|
+ /// i.e. i8, i16, i32, i64, i128 or neither
|
|
|
+ pub fn is_int(&self) -> bool {
|
|
|
+ matches!(self, Self::I8(_) | Self::I16(_) | Self::I32(_) | Self::I64(_) | Self::I128(_))
|
|
|
+ }
|
|
|
+ /// Is Data a unsigned integer (Regardless of bits)
|
|
|
+ ///
|
|
|
+ /// i.e. u8, u16, u32, u64, or u128 or neither
|
|
|
+ pub fn is_uint(&self) -> bool {
|
|
|
+ matches!(self, Self::U8(_) | Self::U16(_) | Self::U32(_) | Self::U64(_) | Self::U128(_))
|
|
|
+ }
|
|
|
+ /// Is Data a f32 or f64 or neither
|
|
|
+ pub fn is_float(&self) -> bool {
|
|
|
+ matches!(self, Self::F32(_) | Self::F64(_))
|
|
|
+ }
|
|
|
+ /// Does Data contain something that holds other Data
|
|
|
+ ///
|
|
|
+ /// `Vec<Data>` or `HashMap<String, Data>` are examples of "nested" Data
|
|
|
+ pub fn is_nested(&self) -> bool {
|
|
|
+ matches!(self, Self::Vec(_) | Self::Map(_))
|
|
|
+ }
|
|
|
+ /// Is Data the Data::Vec variant (`Vec<Data>`)
|
|
|
+ pub fn is_vec(&self) -> bool {
|
|
|
+ matches!(self, Self::Vec(_))
|
|
|
+ }
|
|
|
+ /// Is Data the Data::Map variant (`HashMap<String, Data>`)
|
|
|
+ pub fn is_map(&self) -> bool {
|
|
|
+ matches!(self, Self::Map(_))
|
|
|
+ }
|
|
|
+ /// Push a value into the Data
|
|
|
+ ///
|
|
|
+ /// Must be a Vec or no-op
|
|
|
+ pub fn vec_push(&mut self, v: Data) {
|
|
|
+ if let Self::Vec(vec) = self {
|
|
|
+ vec.push(v);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Assigns/Reassigns a key the value into the Data
|
|
|
+ ///
|
|
|
+ /// Must be a Map or no-op
|
|
|
+ pub fn map_insert(&mut self, k: String, v: Data) {
|
|
|
+ if let Self::Map(hm) = self {
|
|
|
+ hm.insert(k, v);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Obtains the length of String, Vec or Map
|
|
|
+ ///
|
|
|
+ /// All other variants of Data will return 0
|
|
|
+ pub fn len(&self) -> usize {
|
|
|
+ match self {
|
|
|
+ Self::String(s) => s.len(),
|
|
|
+ Self::Vec(v) => v.len(),
|
|
|
+ Self::Map(m) => m.len(),
|
|
|
+ _ => 0,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Obtains the capacity of Vec or Map
|
|
|
+ ///
|
|
|
+ /// All other variants of Data return 0
|
|
|
+ pub fn capacity(&self) -> usize {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.capacity(),
|
|
|
+ Self::Map(m) => m.capacity(),
|
|
|
+ _ => 0,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Reserve {additional} in a Vec or Map
|
|
|
+ ///
|
|
|
+ /// This no-op's if the Data variants are not Vec or Map
|
|
|
+ pub fn reserve(&mut self, additional: usize) {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.reserve(additional),
|
|
|
+ Self::Map(m) => m.reserve(additional),
|
|
|
+ _ => (),
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Shrinks a Vec or Map to fit all that is within it
|
|
|
+ pub fn shrink_to_fit(&mut self) {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.shrink_to_fit(),
|
|
|
+ Self::Map(m) => m.shrink_to_fit(),
|
|
|
+ _ => (),
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Shrinks to a given minimum length for Vec or Map
|
|
|
+ pub fn shrink_to(&mut self, min: usize) {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.shrink_to(min),
|
|
|
+ Self::Map(m) => m.shrink_to(min),
|
|
|
+ _ => (),
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Truncates Vec to a set length, see [Vec::truncate]
|
|
|
+ pub fn vec_truncate(&mut self, len: usize) {
|
|
|
+ if let Self::Vec(v) = self { v.truncate(len) }
|
|
|
+ }
|
|
|
+ /// Removes Vec at given index, see [Vec::remove]
|
|
|
+ pub fn vec_remove(&mut self, index: usize) -> Data {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.remove(index),
|
|
|
+ _ => Data::None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Removes the last item in the Vec, see [Vec::pop]
|
|
|
+ ///
|
|
|
+ /// This will return None also if the Data isn't a Vec
|
|
|
+ pub fn vec_pop(&mut self) -> Option<Data> {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.pop(),
|
|
|
+ _ => None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Clears all in a String, Vec or Map
|
|
|
+ pub fn clear(&mut self) {
|
|
|
+ match self {
|
|
|
+ Self::String(s) => s.clear(),
|
|
|
+ Self::Vec(v) => v.clear(),
|
|
|
+ Self::Map(m) => m.clear(),
|
|
|
+ _ => (),
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Returns if String, Vec or Map is empty (has no elements)
|
|
|
+ pub fn is_empty(&self) -> bool {
|
|
|
+ match self {
|
|
|
+ Self::String(s) => s.is_empty(),
|
|
|
+ Self::Vec(v) => v.is_empty(),
|
|
|
+ Self::Map(m) => m.is_empty(),
|
|
|
+ _ => false,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Resizes the Vec with the given length, assigning new with value
|
|
|
+ pub fn vec_resize(&mut self, len: usize, value: Data) {
|
|
|
+ if let Self::Vec(v) = self { v.resize(len, value) }
|
|
|
+ }
|
|
|
+ /// Obtains the first element in Vec
|
|
|
+ pub fn vec_first(&self) -> Option<&Data> {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.first(),
|
|
|
+ _ => None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Similar to [Data::vec_first] except it obtains as mutable
|
|
|
+ pub fn vec_first_mut(&mut self) -> Option<&mut Data> {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.first_mut(),
|
|
|
+ _ => None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Similar to [Data::vec_first] except obtains the last element of Vec
|
|
|
+ pub fn vec_last(&self) -> Option<&Data> {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.last(),
|
|
|
+ _ => None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Similar to [Data::vec_last] except obtains as mutable
|
|
|
+ pub fn vec_last_mut(&mut self) -> Option<&mut Data> {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.last_mut(),
|
|
|
+ _ => None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Gets by index or range for a Vec
|
|
|
+ pub fn vec_get<I>(&self, index: I) -> Option<&I::Output>
|
|
|
+ where
|
|
|
+ I: SliceIndex<[Data]>,
|
|
|
+ {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.get::<I>(index),
|
|
|
+ _ => None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Gets like [Data::vec_get] except as mutable
|
|
|
+ pub fn vec_get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
|
|
|
+ where
|
|
|
+ I: SliceIndex<[Data]>,
|
|
|
+ {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => v.get_mut::<I>(index),
|
|
|
+ _ => None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pub fn map_contains_key(&self, key: &String) -> bool {
|
|
|
+ match self {
|
|
|
+ Self::Map(hm) => hm.contains_key(key),
|
|
|
+ _ => false,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Get for a Map, see [HashMap::get]
|
|
|
+ pub fn map_get(&self, key: &String) -> Option<&Data> {
|
|
|
+ match self {
|
|
|
+ Self::Map(hm) => hm.get(key),
|
|
|
+ _ => None
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Get as mutable for a Map
|
|
|
+ pub fn map_get_mut(&mut self, key: &String) -> Option<&mut Data> {
|
|
|
+ match self {
|
|
|
+ Self::Map(hm) => hm.get_mut(key),
|
|
|
+ _ => None
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Get Key & Value for a Map
|
|
|
+ pub fn map_get_key_value(&self, key: &String) -> Option<(&String, &Data)> {
|
|
|
+ match self {
|
|
|
+ Self::Map(hm) => hm.get_key_value(key),
|
|
|
+ _ => None
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Removes for a Map
|
|
|
+ pub fn map_remove(&mut self, key: &String) -> Option<Data> {
|
|
|
+ match self {
|
|
|
+ Self::Map(hm) => hm.remove(key),
|
|
|
+ _ => None
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Swaps a with b in a Vec
|
|
|
+ pub fn vec_swap(&mut self, a: usize, b: usize) {
|
|
|
+ if let Self::Vec(v) = self { v.swap(a, b) }
|
|
|
+ }
|
|
|
+ /// Reverses the order of a Vec
|
|
|
+ pub fn vec_reverse(&mut self) {
|
|
|
+ if let Self::Vec(v) = self { v.reverse() }
|
|
|
+ }
|
|
|
+ /// Attempts to form an iterator for Vec
|
|
|
+ ///
|
|
|
+ /// This can fail if Data isn't a Vec
|
|
|
+ pub fn vec_iter(&self) -> Option<Iter<'_, Data>> {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => Some(v.iter()),
|
|
|
+ _ => None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Attempts to form a mutable iterator for Vec
|
|
|
+ ///
|
|
|
+ /// This can fail if Data isn't a Vec
|
|
|
+ pub fn vec_iter_mut(&mut self) -> Option<IterMut<'_, Data>> {
|
|
|
+ match self {
|
|
|
+ Self::Vec(v) => Some(v.iter_mut()),
|
|
|
+ _ => None,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// This will determine the size of signed or unsigned integers and floats
|
|
|
+ ///
|
|
|
+ /// i.e. i32 is 32, u64 is 64, f32 is 32, u128 is 128 (Meanwhile, anything else is 0, String is 0, Bool is 0, etc.)
|
|
|
+ pub fn bit_variant(&self) -> u8 {
|
|
|
+ match self {
|
|
|
+ Self::I8(_) | Self::U8(_) => 8,
|
|
|
+ Self::I16(_) | Self::U16(_) => 16,
|
|
|
+ Self::I32(_) | Self::U32(_) | Self::F32(_) => 32,
|
|
|
+ Self::I64(_) | Self::U64(_) | Self::F64(_) => 64,
|
|
|
+ Self::I128(_) | Self::U128(_) => 128,
|
|
|
+ _ => 0
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|