use std::collections::BTreeMap;
use std::hash::{Hash, Hasher};
use std::{cmp, io};
use crate::{ArgLength, Array, CtrlByte, DataType, Error, Float, Integer, Major, Map, Result, SimpleValue, Tag};
fn u128_from_bytes(bytes: &[u8]) -> Result<u128> {
let mut buf = [0_u8; 16];
let offset = buf.len().checked_sub(bytes.len()).ok_or(Error::Overflow)?;
buf[offset..].copy_from_slice(bytes);
Ok(u128::from_be_bytes(buf))
}
fn read_vec(reader: &mut impl io::Read, len: u64) -> Result<Vec<u8>> {
use io::Read;
let len_usize = usize::try_from(len).map_err(|_| Error::LengthTooLarge)?;
let mut buf = Vec::with_capacity(len_usize.min(100_000_000)); let bytes_read = reader.take(len).read_to_end(&mut buf)?;
if bytes_read == len_usize {
Ok(buf)
} else {
Err(Error::UnexpectedEof)
}
}
#[derive(Debug, Clone)]
pub enum Value {
SimpleValue(SimpleValue),
Unsigned(u64),
Negative(u64),
Float(Float),
ByteString(Vec<u8>),
TextString(String),
Array(Vec<Value>),
Map(BTreeMap<Value, Value>),
Tag(u64, Box<Value>),
}
impl Default for Value {
fn default() -> Self {
Self::null()
}
}
impl PartialEq for Value {
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == cmp::Ordering::Equal
}
}
impl Eq for Value {}
impl Ord for Value {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.cbor_major()
.cmp(&other.cbor_major())
.then_with(|| self.cbor_argument().cmp(&other.cbor_argument()))
.then_with(|| match (self, other) {
(Self::TextString(a), Self::TextString(b)) => a.cmp(b),
(Self::ByteString(a), Self::ByteString(b)) => a.cmp(b),
(Self::Array(a), Self::Array(b)) => a.cmp(b),
(Self::Map(a), Self::Map(b)) => a.cmp(b),
(Self::Tag(_, a), Self::Tag(_, b)) => a.cmp(b),
_ => std::cmp::Ordering::Equal,
})
}
}
impl PartialOrd for Value {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Hash for Value {
fn hash<H: Hasher>(&self, state: &mut H) {
self.cbor_major().hash(state);
self.cbor_argument().hash(state);
match self {
Self::TextString(s) => s.hash(state),
Self::ByteString(b) => b.hash(state),
Self::Array(a) => a.hash(state),
Self::Map(m) => {
for (k, v) in m {
k.hash(state);
v.hash(state);
}
}
Self::Tag(_, v) => v.hash(state),
_ => {}
}
}
}
impl Value {
#[must_use]
pub fn encode(&self) -> Vec<u8> {
let mut bytes = Vec::new();
self.write_to(&mut bytes).unwrap();
bytes
}
pub fn decode(mut bytes: &[u8]) -> Result<Self> {
Self::read_from(&mut bytes)
}
pub fn read_from(reader: &mut impl io::Read) -> Result<Self> {
let ctrl_byte = {
let mut buf = [0];
reader.read_exact(&mut buf)?;
buf[0]
};
let is_float = matches!(ctrl_byte, CtrlByte::F16 | CtrlByte::F32 | CtrlByte::F64);
let major = ctrl_byte >> 5;
let info = ctrl_byte & 0x1f;
let argument = {
let mut buf = [0; 8];
if info < ArgLength::U8 {
buf[7] = info;
} else {
match info {
ArgLength::U8 => reader.read_exact(&mut buf[7..])?,
ArgLength::U16 => reader.read_exact(&mut buf[6..])?,
ArgLength::U32 => reader.read_exact(&mut buf[4..])?,
ArgLength::U64 => reader.read_exact(&mut buf)?,
_ => return Err(Error::InvalidEncoding),
}
}
u64::from_be_bytes(buf)
};
if !is_float {
let non_deterministic = match info {
ArgLength::U8 => argument < ArgLength::U8.into(),
ArgLength::U16 => argument <= u8::MAX.into(),
ArgLength::U32 => argument <= u16::MAX.into(),
ArgLength::U64 => argument <= u32::MAX.into(),
_ => false,
};
if non_deterministic {
return Err(Error::InvalidEncoding);
}
}
let this = match major {
Major::UNSIGNED => Self::Unsigned(argument),
Major::NEGATIVE => Self::Negative(argument),
Major::BYTE_STRING => Self::ByteString(read_vec(reader, argument)?),
Major::TEXT_STRING => {
let bytes = read_vec(reader, argument)?;
let string = String::from_utf8(bytes).map_err(|_| Error::InvalidUtf8)?;
Self::TextString(string)
}
Major::ARRAY => {
let mut vec = Vec::with_capacity(argument.try_into().unwrap());
for _ in 0..argument {
vec.push(Self::read_from(reader)?);
}
Self::Array(vec)
}
Major::MAP => {
let mut map = BTreeMap::new();
let mut prev = None;
for _ in 0..argument {
let key = Self::read_from(reader)?;
let value = Self::read_from(reader)?;
if let Some((prev_key, prev_value)) = prev.take() {
if prev_key >= key {
return Err(Error::InvalidEncoding);
}
map.insert(prev_key, prev_value);
}
prev = Some((key, value));
}
if let Some((key, value)) = prev.take() {
map.insert(key, value);
}
Self::Map(map)
}
Major::TAG => {
let content = Box::new(Self::read_from(reader)?);
if matches!(argument, Tag::POS_BIG_INT | Tag::NEG_BIG_INT)
&& let Ok(bigint) = content.as_bytes()
{
let valid = bigint.len() >= 8 && bigint[0] != 0;
if !valid {
return Err(Error::InvalidEncoding);
}
}
Self::Tag(argument, content)
}
Major::SIMPLE_VALUE => match info {
0..=ArgLength::U8 => SimpleValue::from_u8(argument as u8)
.map(Self::SimpleValue)
.map_err(|_| Error::InvalidEncoding)?,
ArgLength::U16 => Self::Float(Float::from_u16(argument as u16)),
ArgLength::U32 => Self::Float(Float::from_u32(argument as u32)?),
ArgLength::U64 => Self::Float(Float::from_u64(argument)?),
_ => return Err(Error::InvalidEncoding),
},
_ => unreachable!(),
};
Ok(this)
}
pub fn write_to(&self, writer: &mut impl io::Write) -> Result<()> {
let major = self.cbor_major();
let (info, argument) = self.cbor_argument();
let ctrl_byte = major << 5 | info;
writer.write_all(&[ctrl_byte])?;
let buf = argument.to_be_bytes();
match info {
ArgLength::U8 => writer.write_all(&buf[7..])?,
ArgLength::U16 => writer.write_all(&buf[6..])?,
ArgLength::U32 => writer.write_all(&buf[4..])?,
ArgLength::U64 => writer.write_all(&buf)?,
_ => (), }
match self {
Value::ByteString(bytes) => writer.write_all(bytes)?,
Value::TextString(string) => writer.write_all(string.as_bytes())?,
Value::Tag(_number, content) => content.write_to(writer)?,
Value::Array(values) => {
for value in values {
value.write_to(writer)?;
}
}
Value::Map(map) => {
for (key, value) in map {
key.write_to(writer)?;
value.write_to(writer)?;
}
}
_ => (),
}
Ok(())
}
fn cbor_major(&self) -> u8 {
match self {
Value::Unsigned(_) => Major::UNSIGNED,
Value::Negative(_) => Major::NEGATIVE,
Value::ByteString(_) => Major::BYTE_STRING,
Value::TextString(_) => Major::TEXT_STRING,
Value::Array(_) => Major::ARRAY,
Value::Map(_) => Major::MAP,
Value::Tag(_, _) => Major::TAG,
Value::SimpleValue(_) => Major::SIMPLE_VALUE,
Value::Float(_) => Major::SIMPLE_VALUE,
}
}
fn cbor_argument(&self) -> (u8, u64) {
fn arg(value: u64) -> (u8, u64) {
if value < ArgLength::U8.into() {
(value as u8, value)
} else {
let info = match value {
0x00..=0xFF => ArgLength::U8,
0x100..=0xFFFF => ArgLength::U16,
0x10000..=0xFFFF_FFFF => ArgLength::U32,
_ => ArgLength::U64,
};
(info, value)
}
}
match self {
Value::Unsigned(value) => arg(*value),
Value::Negative(value) => arg(*value),
Value::ByteString(vec) => arg(vec.len().try_into().unwrap()),
Value::TextString(str) => arg(str.len().try_into().unwrap()),
Value::Array(vec) => arg(vec.len().try_into().unwrap()),
Value::Map(map) => arg(map.len().try_into().unwrap()),
Value::Tag(number, _) => arg(*number),
Value::SimpleValue(value) => arg(value.0.into()),
Value::Float(float) => float.cbor_argument(),
}
}
#[must_use]
pub const fn null() -> Self {
Self::SimpleValue(SimpleValue::NULL)
}
pub fn simple_value(value: impl TryInto<SimpleValue>) -> Self {
match value.try_into() {
Ok(sv) => Self::SimpleValue(sv),
Err(_) => panic!("Invalid simple value"),
}
}
pub fn integer(value: impl Into<Integer>) -> Self {
value.into().into_value()
}
pub fn float(value: impl Into<Float>) -> Self {
Self::Float(value.into())
}
pub fn array(array: impl Into<Array>) -> Self {
Self::Array(array.into().0)
}
pub fn map(map: impl Into<Map>) -> Self {
Self::Map(map.into().0)
}
pub fn tag(number: u64, content: impl Into<Value>) -> Self {
Self::Tag(number, Box::new(content.into()))
}
#[must_use]
pub const fn data_type(&self) -> DataType {
match self {
Self::SimpleValue(sv) => sv.data_type(),
Self::Unsigned(_) | Self::Negative(_) => DataType::Int,
Self::Float(float) => float.data_type(),
Self::TextString(_) => DataType::Text,
Self::ByteString(_) => DataType::Bytes,
Self::Array(_) => DataType::Array,
Self::Map(_) => DataType::Map,
Self::Tag(Tag::POS_BIG_INT | Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => {
DataType::BigInt
}
Self::Tag(_, _) => DataType::Tag,
}
}
pub const fn to_bool(&self) -> Result<bool> {
match self {
Self::SimpleValue(sv) => sv.to_bool(),
_ => Err(Error::IncompatibleType),
}
}
pub const fn to_simple_value(&self) -> Result<u8> {
match self {
Self::SimpleValue(sv) => Ok(sv.0),
_ => Err(Error::IncompatibleType),
}
}
pub const fn to_u8(&self) -> Result<u8> {
match self {
Self::Unsigned(x) if *x <= u8::MAX as u64 => Ok(*x as u8),
Self::Unsigned(_) => Err(Error::Overflow),
Self::Negative(_) => Err(Error::NegativeUnsigned),
Self::Tag(Tag::POS_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
Self::Tag(Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::NegativeUnsigned),
_ => Err(Error::IncompatibleType),
}
}
pub const fn to_u16(&self) -> Result<u16> {
match self {
Self::Unsigned(x) if *x <= u16::MAX as u64 => Ok(*x as u16),
Self::Unsigned(_) => Err(Error::Overflow),
Self::Negative(_) => Err(Error::NegativeUnsigned),
Self::Tag(Tag::POS_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
Self::Tag(Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::NegativeUnsigned),
_ => Err(Error::IncompatibleType),
}
}
pub const fn to_u32(&self) -> Result<u32> {
match self {
Self::Unsigned(x) if *x <= u32::MAX as u64 => Ok(*x as u32),
Self::Unsigned(_) => Err(Error::Overflow),
Self::Negative(_) => Err(Error::NegativeUnsigned),
Self::Tag(Tag::POS_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
Self::Tag(Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::NegativeUnsigned),
_ => Err(Error::IncompatibleType),
}
}
pub const fn to_u64(&self) -> Result<u64> {
match self {
Self::Unsigned(x) => Ok(*x),
Self::Negative(_) => Err(Error::NegativeUnsigned),
Self::Tag(Tag::POS_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
Self::Tag(Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::NegativeUnsigned),
_ => Err(Error::IncompatibleType),
}
}
pub fn to_u128(&self) -> Result<u128> {
match self {
Self::Unsigned(x) => Ok(*x as u128),
Self::Negative(_) => Err(Error::NegativeUnsigned),
Self::Tag(Tag::POS_BIG_INT, content) => u128_from_bytes(content.as_bytes()?),
Self::Tag(Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::NegativeUnsigned),
_ => Err(Error::IncompatibleType),
}
}
#[cfg(target_pointer_width = "32")]
pub const fn to_usize(&self) -> Result<usize> {
match self {
Self::Unsigned(x) if *x <= u32::MAX as u64 => Ok(*x as usize),
Self::Unsigned(_) => Err(Error::Overflow),
Self::Negative(_) => Err(Error::NegativeUnsigned),
Self::Tag(TAG_POS_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
Self::Tag(TAG_NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::NegativeUnsigned),
_ => Err(Error::IncompatibleType),
}
}
#[cfg(target_pointer_width = "64")]
pub const fn to_usize(&self) -> Result<usize> {
match self {
Self::Unsigned(x) => Ok(*x as usize),
Self::Negative(_) => Err(Error::NegativeUnsigned),
Self::Tag(Tag::POS_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
Self::Tag(Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::NegativeUnsigned),
_ => Err(Error::IncompatibleType),
}
}
pub const fn to_i8(&self) -> Result<i8> {
match self {
Self::Unsigned(x) if *x <= i8::MAX as u64 => Ok(*x as i8),
Self::Unsigned(_) => Err(Error::Overflow),
Self::Negative(x) if *x <= i8::MAX as u64 => Ok((!*x) as i8),
Self::Negative(_) => Err(Error::Overflow),
Self::Tag(Tag::POS_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
Self::Tag(Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
_ => Err(Error::IncompatibleType),
}
}
pub const fn to_i16(&self) -> Result<i16> {
match self {
Self::Unsigned(x) if *x <= i16::MAX as u64 => Ok(*x as i16),
Self::Unsigned(_) => Err(Error::Overflow),
Self::Negative(x) if *x <= i16::MAX as u64 => Ok((!*x) as i16),
Self::Negative(_) => Err(Error::Overflow),
Self::Tag(Tag::POS_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
Self::Tag(Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
_ => Err(Error::IncompatibleType),
}
}
pub const fn to_i32(&self) -> Result<i32> {
match self {
Self::Unsigned(x) if *x <= i32::MAX as u64 => Ok(*x as i32),
Self::Unsigned(_) => Err(Error::Overflow),
Self::Negative(x) if *x <= i32::MAX as u64 => Ok((!*x) as i32),
Self::Negative(_) => Err(Error::Overflow),
Self::Tag(Tag::POS_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
Self::Tag(Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
_ => Err(Error::IncompatibleType),
}
}
pub const fn to_i64(&self) -> Result<i64> {
match self {
Self::Unsigned(x) if *x <= i64::MAX as u64 => Ok(*x as i64),
Self::Unsigned(_) => Err(Error::Overflow),
Self::Negative(x) if *x <= i64::MAX as u64 => Ok((!*x) as i64),
Self::Negative(_) => Err(Error::Overflow),
Self::Tag(Tag::POS_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
Self::Tag(Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
_ => Err(Error::IncompatibleType),
}
}
pub fn to_i128(&self) -> Result<i128> {
match self {
Self::Unsigned(x) => Ok(*x as i128),
Self::Negative(x) => Ok(!(*x as i128)),
Self::Tag(Tag::POS_BIG_INT, content) => match u128_from_bytes(content.as_bytes()?)? {
value if value <= i128::MAX as u128 => Ok(value as i128),
_ => Err(Error::Overflow),
},
Self::Tag(Tag::NEG_BIG_INT, content) => match u128_from_bytes(content.as_bytes()?)? {
value if value <= i128::MAX as u128 => Ok((!value) as i128),
_ => Err(Error::Overflow),
},
_ => Err(Error::IncompatibleType),
}
}
#[cfg(target_pointer_width = "32")]
pub const fn to_isize(&self) -> Result<isize> {
match self {
Self::Unsigned(x) if *x <= i32::MAX as u64 => Ok(*x as isize),
Self::Unsigned(_) => Err(Error::Overflow),
Self::Negative(x) if *x <= i32::MAX as u64 => Ok((!*x) as isize),
Self::Negative(_) => Err(Error::Overflow),
Self::Tag(TAG_POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
Self::Tag(TAG_NEG_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
_ => Err(Error::IncompatibleType),
}
}
#[cfg(target_pointer_width = "64")]
pub const fn to_isize(&self) -> Result<isize> {
match self {
Self::Unsigned(x) if *x <= i64::MAX as u64 => Ok(*x as isize),
Self::Unsigned(_) => Err(Error::Overflow),
Self::Negative(x) if *x <= i64::MAX as u64 => Ok((!*x) as isize),
Self::Negative(_) => Err(Error::Overflow),
Self::Tag(Tag::POS_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
Self::Tag(Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => Err(Error::Overflow),
_ => Err(Error::IncompatibleType),
}
}
pub fn to_f32(&self) -> Result<f32> {
match self {
Self::Float(float) => float.to_f32(),
_ => Err(Error::IncompatibleType),
}
}
pub fn to_f64(&self) -> Result<f64> {
match self {
Self::Float(float) => Ok(float.to_f64()),
_ => Err(Error::IncompatibleType),
}
}
pub fn as_bytes(&self) -> Result<&[u8]> {
match self {
Self::ByteString(vec) => Ok(vec.as_slice()),
_ => Err(Error::IncompatibleType),
}
}
pub const fn as_bytes_mut(&mut self) -> Result<&mut Vec<u8>> {
match self {
Self::ByteString(vec) => Ok(vec),
_ => Err(Error::IncompatibleType),
}
}
pub fn into_bytes(self) -> Result<Vec<u8>> {
match self {
Self::ByteString(vec) => Ok(vec),
_ => Err(Error::IncompatibleType),
}
}
pub fn as_str(&self) -> Result<&str> {
match self {
Self::TextString(s) => Ok(s.as_str()),
_ => Err(Error::IncompatibleType),
}
}
pub const fn as_string_mut(&mut self) -> Result<&mut String> {
match self {
Self::TextString(s) => Ok(s),
_ => Err(Error::IncompatibleType),
}
}
pub fn into_string(self) -> Result<String> {
match self {
Self::TextString(s) => Ok(s),
_ => Err(Error::IncompatibleType),
}
}
pub fn as_array(&self) -> Result<&[Value]> {
match self {
Self::Array(v) => Ok(v.as_slice()),
_ => Err(Error::IncompatibleType),
}
}
pub const fn as_array_mut(&mut self) -> Result<&mut Vec<Value>> {
match self {
Self::Array(v) => Ok(v),
_ => Err(Error::IncompatibleType),
}
}
pub fn into_array(self) -> Result<Vec<Value>> {
match self {
Self::Array(v) => Ok(v),
_ => Err(Error::IncompatibleType),
}
}
pub const fn as_map(&self) -> Result<&BTreeMap<Value, Value>> {
match self {
Self::Map(m) => Ok(m),
_ => Err(Error::IncompatibleType),
}
}
pub const fn as_map_mut(&mut self) -> Result<&mut BTreeMap<Value, Value>> {
match self {
Self::Map(m) => Ok(m),
_ => Err(Error::IncompatibleType),
}
}
pub fn into_map(self) -> Result<BTreeMap<Value, Value>> {
match self {
Self::Map(m) => Ok(m),
_ => Err(Error::IncompatibleType),
}
}
pub const fn tag_number(&self) -> Result<u64> {
match self {
Self::Tag(number, _content) => Ok(*number),
_ => Err(Error::IncompatibleType),
}
}
pub const fn tag_content(&self) -> Result<&Self> {
match self {
Self::Tag(_tag, content) => Ok(content),
_ => Err(Error::IncompatibleType),
}
}
pub const fn tag_content_mut(&mut self) -> Result<&mut Self> {
match self {
Self::Tag(_, value) => Ok(value),
_ => Err(Error::IncompatibleType),
}
}
pub fn as_tag(&self) -> Result<(u64, &Value)> {
match self {
Self::Tag(number, content) => Ok((*number, content)),
_ => Err(Error::IncompatibleType),
}
}
pub fn as_tag_mut(&mut self) -> Result<(u64, &mut Value)> {
match self {
Self::Tag(number, content) => Ok((*number, content)),
_ => Err(Error::IncompatibleType),
}
}
pub fn into_tag(self) -> Result<(u64, Value)> {
match self {
Self::Tag(number, content) => Ok((number, *content)),
_ => Err(Error::IncompatibleType),
}
}
pub fn remove_tag(&mut self) -> Option<u64> {
let mut result = None;
if let Self::Tag(number, content) = self {
result = Some(*number);
*self = std::mem::take(content);
}
result
}
pub fn remove_all_tags(&mut self) -> Vec<u64> {
let mut tags = Vec::new();
while let Self::Tag(number, content) = self {
tags.push(*number);
*self = std::mem::take(content);
}
tags
}
#[must_use]
pub const fn untagged(&self) -> &Self {
let mut result = self;
while let Self::Tag(_, data_item) = result {
result = data_item;
}
result
}
pub const fn untagged_mut(&mut self) -> &mut Self {
let mut result = self;
while let Self::Tag(_, data_item) = result {
result = data_item;
}
result
}
#[must_use]
pub fn into_untagged(mut self) -> Self {
while let Self::Tag(_number, content) = self {
self = *content;
}
self
}
}
impl From<SimpleValue> for Value {
fn from(value: SimpleValue) -> Self {
Self::SimpleValue(value)
}
}
impl From<bool> for Value {
fn from(value: bool) -> Self {
Self::SimpleValue(SimpleValue::from_bool(value))
}
}
impl From<Integer> for Value {
fn from(value: Integer) -> Self {
value.into_value()
}
}
impl From<u8> for Value {
fn from(value: u8) -> Self {
Integer::from(value).into_value()
}
}
impl From<u16> for Value {
fn from(value: u16) -> Self {
Integer::from(value).into_value()
}
}
impl From<u32> for Value {
fn from(value: u32) -> Self {
Integer::from(value).into_value()
}
}
impl From<u64> for Value {
fn from(value: u64) -> Self {
Integer::from(value).into_value()
}
}
impl From<u128> for Value {
fn from(value: u128) -> Self {
Integer::from(value).into_value()
}
}
impl From<usize> for Value {
fn from(value: usize) -> Self {
Integer::from(value).into_value()
}
}
impl From<i8> for Value {
fn from(value: i8) -> Self {
Integer::from(value).into_value()
}
}
impl From<i16> for Value {
fn from(value: i16) -> Self {
Integer::from(value).into_value()
}
}
impl From<i32> for Value {
fn from(value: i32) -> Self {
Integer::from(value).into_value()
}
}
impl From<i64> for Value {
fn from(value: i64) -> Self {
Integer::from(value).into_value()
}
}
impl From<i128> for Value {
fn from(value: i128) -> Self {
Integer::from(value).into_value()
}
}
impl From<isize> for Value {
fn from(value: isize) -> Self {
Integer::from(value).into_value()
}
}
impl From<Float> for Value {
fn from(value: Float) -> Self {
Self::Float(value)
}
}
impl From<f32> for Value {
fn from(value: f32) -> Self {
Self::Float(value.into())
}
}
impl From<f64> for Value {
fn from(value: f64) -> Self {
Self::Float(value.into())
}
}
impl From<&str> for Value {
fn from(value: &str) -> Self {
Self::TextString(value.into())
}
}
impl From<String> for Value {
fn from(value: String) -> Self {
Self::TextString(value)
}
}
impl From<&String> for Value {
fn from(value: &String) -> Self {
Self::TextString(value.clone())
}
}
impl From<Box<str>> for Value {
fn from(value: Box<str>) -> Self {
Self::TextString(value.into())
}
}
impl From<Vec<u8>> for Value {
fn from(value: Vec<u8>) -> Self {
Self::ByteString(value)
}
}
impl From<&[u8]> for Value {
fn from(value: &[u8]) -> Self {
Self::ByteString(value.to_vec())
}
}
impl<const N: usize> From<[u8; N]> for Value {
fn from(value: [u8; N]) -> Self {
Self::ByteString(value.to_vec())
}
}
impl<const N: usize> From<&[u8; N]> for Value {
fn from(value: &[u8; N]) -> Self {
Self::ByteString(value.to_vec())
}
}
impl From<Box<[u8]>> for Value {
fn from(value: Box<[u8]>) -> Self {
Self::ByteString(Vec::from(value))
}
}
impl From<Vec<Value>> for Value {
fn from(value: Vec<Value>) -> Self {
Self::Array(value)
}
}
impl<const N: usize> From<[Value; N]> for Value {
fn from(value: [Value; N]) -> Self {
Self::Array(value.to_vec())
}
}
impl From<Box<[Value]>> for Value {
fn from(value: Box<[Value]>) -> Self {
Self::Array(value.to_vec())
}
}
impl From<Array> for Value {
fn from(value: Array) -> Self {
Self::Array(value.into_inner())
}
}
impl From<Map> for Value {
fn from(value: Map) -> Self {
Self::Map(value.into_inner())
}
}
impl From<BTreeMap<Value, Value>> for Value {
fn from(value: BTreeMap<Value, Value>) -> Self {
Self::Map(value)
}
}
impl TryFrom<Value> for bool {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_bool()
}
}
impl TryFrom<Value> for SimpleValue {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
match value {
Value::SimpleValue(sv) => Ok(sv),
_ => Err(Error::IncompatibleType),
}
}
}
impl TryFrom<Value> for u8 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_u8()
}
}
impl TryFrom<Value> for u16 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_u16()
}
}
impl TryFrom<Value> for u32 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_u32()
}
}
impl TryFrom<Value> for u64 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_u64()
}
}
impl TryFrom<Value> for u128 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_u128()
}
}
impl TryFrom<Value> for usize {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_usize()
}
}
impl TryFrom<Value> for i8 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_i8()
}
}
impl TryFrom<Value> for i16 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_i16()
}
}
impl TryFrom<Value> for i32 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_i32()
}
}
impl TryFrom<Value> for i64 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_i64()
}
}
impl TryFrom<Value> for i128 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_i128()
}
}
impl TryFrom<Value> for isize {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_isize()
}
}
impl TryFrom<Value> for f32 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_f32()
}
}
impl TryFrom<Value> for f64 {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.to_f64()
}
}
impl TryFrom<Value> for Float {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
match value {
Value::Float(f) => Ok(f),
_ => Err(Error::IncompatibleType),
}
}
}
impl TryFrom<Value> for Integer {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
Integer::from_value(value)
}
}
impl TryFrom<Value> for String {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.into_string()
}
}
impl TryFrom<Value> for Vec<u8> {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.into_bytes()
}
}
impl TryFrom<Value> for Vec<Value> {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.into_array()
}
}
impl TryFrom<Value> for BTreeMap<Value, Value> {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.into_map()
}
}
impl TryFrom<Value> for Array {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.into_array().map(Array::from)
}
}
impl TryFrom<Value> for Map {
type Error = Error;
fn try_from(value: Value) -> Result<Self> {
value.into_map().map(Map::from)
}
}