Skip to main content

cbor_core/
value.rs

1use std::collections::BTreeMap;
2use std::hash::{Hash, Hasher};
3use std::ops::{Index, IndexMut};
4use std::{cmp, io};
5
6use crate::{ArgLength, Array, CtrlByte, DataType, Error, Float, Integer, Major, Map, Result, SimpleValue, Tag};
7
8fn u128_from_bytes(bytes: &[u8]) -> Result<u128> {
9    let mut buf = [0_u8; 16];
10    let offset = buf.len().checked_sub(bytes.len()).ok_or(Error::Overflow)?;
11    buf[offset..].copy_from_slice(bytes);
12    Ok(u128::from_be_bytes(buf))
13}
14
15fn read_vec(reader: &mut impl io::Read, len: u64) -> Result<Vec<u8>> {
16    use io::Read;
17
18    let len_usize = usize::try_from(len).map_err(|_| Error::LengthTooLarge)?;
19
20    let mut buf = Vec::with_capacity(len_usize.min(100_000_000)); // Mitigate OOM
21    let bytes_read = reader.take(len).read_to_end(&mut buf)?;
22
23    if bytes_read == len_usize {
24        Ok(buf)
25    } else {
26        Err(Error::UnexpectedEof)
27    }
28}
29
30/// A single CBOR data item.
31///
32/// `Value` covers all CBOR major types: integers, floats, byte and text
33/// strings, arrays, maps, tagged values, and simple values (null, booleans).
34/// It encodes deterministically and decodes only canonical input.
35///
36/// # Creating values
37///
38/// Rust primitives convert via [`From`]:
39///
40/// ```
41/// use cbor_core::Value;
42///
43/// let n = Value::from(42_u32);
44/// let s = Value::from("hello");
45/// let b = Value::from(true);
46/// ```
47///
48/// For arrays and maps the `array!` and `map!` macros are convenient:
49///
50/// ```
51/// use cbor_core::{Value, array, map};
52///
53/// let a = array![1, 2, 3];
54/// let m = map! { "x" => 10, "y" => 20 };
55/// ```
56///
57/// Arrays and maps can also be built from standard Rust collections.
58/// Slices, `Vec`s, fixed-size arrays, `BTreeMap`s, `HashMap`s, and
59/// slices of key-value pairs all convert automatically:
60///
61/// ```
62/// use cbor_core::Value;
63/// use std::collections::HashMap;
64///
65/// // Array from a slice
66/// let a = Value::array([1_u32, 2, 3].as_slice());
67///
68/// // Map from a HashMap
69/// let mut hm = HashMap::new();
70/// hm.insert(1_u32, 2_u32);
71/// let m = Value::map(&hm);
72///
73/// // Map from key-value pairs
74/// let m = Value::map([("x", 10), ("y", 20)]);
75/// ```
76///
77/// Use `()` to create empty arrays or maps without spelling out a type:
78///
79/// ```
80/// use cbor_core::Value;
81///
82/// let empty_array = Value::array(());
83/// let empty_map = Value::map(());
84///
85/// assert_eq!(empty_array.as_array().unwrap().len(), 0);
86/// assert_eq!(empty_map.as_map().unwrap().len(), 0);
87/// ```
88///
89/// Named constructors are available for cases where `From` is ambiguous:
90///
91/// | Constructor | Builds |
92/// |---|---|
93/// | [`Value::null()`] | Null simple value |
94/// | [`Value::simple_value(v)`](Value::simple_value) | Arbitrary simple value |
95/// | [`Value::float(v)`](Value::float) | Float in shortest CBOR form |
96/// | [`Value::array(v)`](Value::array) | Array from slice, `Vec`, or fixed-size array |
97/// | [`Value::map(v)`](Value::map) | Map from `BTreeMap`, `HashMap`, slice of pairs, etc. |
98/// | [`Value::tag(n, v)`](Value::tag) | Tagged value |
99///
100/// # Encoding and decoding
101///
102/// ```
103/// use cbor_core::Value;
104///
105/// let original = Value::from(-1000_i32);
106/// let bytes = original.encode();
107/// let decoded = Value::decode(&bytes).unwrap();
108/// assert_eq!(original, decoded);
109/// ```
110///
111/// For streaming use, [`write_to`](Value::write_to) and
112/// [`read_from`](Value::read_from) operate on any `io::Write` / `io::Read`.
113///
114/// # Accessors
115///
116/// Accessor methods extract or borrow the inner data of each variant.
117/// All return `Result<T>`, yielding `Err(Error::IncompatibleType)` on a
118/// type mismatch. The naming follows Rust conventions:
119///
120/// | Prefix | Meaning | Returns |
121/// |---|---|---|
122/// | `as_*` | Borrow inner data | `&T` or `&mut T` (with `_mut`) |
123/// | `to_*` | Convert or narrow | Owned `Copy` type (`u8`, `f32`, ...) |
124/// | `into_*` | Consume self, extract | Owned `T` |
125/// | no prefix | Trivial property | `Copy` scalar |
126///
127/// ## Simple values
128///
129/// In CBOR, booleans and null are not distinct types but specific simple
130/// values: `false` is 20, `true` is 21, `null` is 22. This means a
131/// boolean value is always also a simple value. [`to_bool`](Self::to_bool)
132/// provides typed access to `true`/`false`, while
133/// [`to_simple_value`](Self::to_simple_value) works on any simple value
134/// including booleans and null.
135///
136/// | Method | Returns | Notes |
137/// |---|---|---|
138/// | [`to_simple_value`](Self::to_simple_value) | `Result<u8>` | Raw simple value number |
139/// | [`to_bool`](Self::to_bool) | `Result<bool>` | Only for `true`/`false` |
140///
141/// ```
142/// use cbor_core::Value;
143///
144/// let v = Value::from(true);
145/// assert_eq!(v.to_bool().unwrap(), true);
146/// assert_eq!(v.to_simple_value().unwrap(), 21); // CBOR true = simple(21)
147///
148/// // null is also a simple value
149/// let n = Value::null();
150/// assert!(n.to_bool().is_err());              // not a boolean
151/// assert_eq!(n.to_simple_value().unwrap(), 22); // but is simple(22)
152/// ```
153///
154/// ## Integers
155///
156/// CBOR has effectively four integer types (unsigned or negative, and
157/// normal or big integer) with different internal representations.
158/// This is handled transparently by the API.
159///
160/// The `to_*` accessors perform checked
161/// narrowing into any Rust integer type, returning `Err(Overflow)` if
162/// the value does not fit, or `Err(NegativeUnsigned)` when extracting a
163/// negative value into an unsigned type.
164///
165/// | Method | Returns |
166/// |---|---|
167/// | [`to_u8`](Self::to_u8) .. [`to_u128`](Self::to_u128), [`to_usize`](Self::to_usize) | `Result<uN>` |
168/// | [`to_i8`](Self::to_i8) .. [`to_i128`](Self::to_i128), [`to_isize`](Self::to_isize) | `Result<iN>` |
169///
170/// ```
171/// use cbor_core::Value;
172///
173/// let v = Value::from(1000_u32);
174/// assert_eq!(v.to_u32().unwrap(), 1000);
175/// assert_eq!(v.to_i64().unwrap(), 1000);
176/// assert!(v.to_u8().is_err()); // overflow
177///
178/// let neg = Value::from(-5_i32);
179/// assert_eq!(neg.to_i8().unwrap(), -5);
180/// assert!(neg.to_u32().is_err()); // negative unsigned
181/// ```
182///
183/// ## Floats
184///
185/// Floats are stored internally in their shortest CBOR encoding (`f16`,
186/// `f32`, or `f64`). [`to_f64`](Self::to_f64) always succeeds since every
187/// float can widen to `f64`. [`to_f32`](Self::to_f32) fails with
188/// `Err(Precision)` if the value is stored as `f64`.
189/// A float internally stored as `f16` can always be converted to either
190/// an `f32` or `f64` for obvious reasons.
191///
192/// | Method | Returns |
193/// |---|---|
194/// | [`to_f32`](Self::to_f32) | `Result<f32>` (fails for f64 values) |
195/// | [`to_f64`](Self::to_f64) | `Result<f64>` |
196///
197/// ```
198/// use cbor_core::Value;
199///
200/// let v = Value::from(2.5_f32);
201/// assert_eq!(v.to_f64().unwrap(), 2.5);
202/// assert_eq!(v.to_f32().unwrap(), 2.5);
203/// ```
204///
205/// ## Byte strings
206///
207/// Byte strings are stored as `Vec<u8>`. Use [`as_bytes`](Self::as_bytes)
208/// for a borrowed slice, or [`into_bytes`](Self::into_bytes) to take
209/// ownership without copying.
210///
211/// | Method | Returns |
212/// |---|---|
213/// | [`as_bytes`](Self::as_bytes) | `Result<&[u8]>` |
214/// | [`as_bytes_mut`](Self::as_bytes_mut) | `Result<&mut Vec<u8>>` |
215/// | [`into_bytes`](Self::into_bytes) | `Result<Vec<u8>>` |
216///
217/// ```
218/// use cbor_core::Value;
219///
220/// let mut v = Value::from(vec![1_u8, 2, 3]);
221/// v.as_bytes_mut().unwrap().push(4);
222/// assert_eq!(v.as_bytes().unwrap(), &[1, 2, 3, 4]);
223/// ```
224///
225/// ## Text strings
226///
227/// Text strings are stored as `String` (guaranteed valid UTF-8 by the
228/// decoder). Use [`as_str`](Self::as_str) for a borrowed `&str`, or
229/// [`into_string`](Self::into_string) to take ownership.
230///
231/// | Method | Returns |
232/// |---|---|
233/// | [`as_str`](Self::as_str) | `Result<&str>` |
234/// | [`as_string_mut`](Self::as_string_mut) | `Result<&mut String>` |
235/// | [`into_string`](Self::into_string) | `Result<String>` |
236///
237/// ```
238/// use cbor_core::Value;
239///
240/// let v = Value::from("hello");
241/// assert_eq!(v.as_str().unwrap(), "hello");
242///
243/// // Modify in place
244/// let mut v = Value::from("hello");
245/// v.as_string_mut().unwrap().push_str(" world");
246/// assert_eq!(v.as_str().unwrap(), "hello world");
247/// ```
248///
249/// ## Arrays
250///
251/// Arrays are stored as `Vec<Value>`. Use [`as_array`](Self::as_array)
252/// to borrow the elements as a slice, or [`as_array_mut`](Self::as_array_mut)
253/// to modify them in place.
254///
255/// | Method | Returns |
256/// |---|---|
257/// | [`as_array`](Self::as_array) | `Result<&[Value]>` |
258/// | [`as_array_mut`](Self::as_array_mut) | `Result<&mut Vec<Value>>` |
259/// | [`into_array`](Self::into_array) | `Result<Vec<Value>>` |
260///
261/// ```
262/// use cbor_core::{Value, array};
263///
264/// let v = array![10, 20, 30];
265/// let items = v.as_array().unwrap();
266/// assert_eq!(items[1].to_u32().unwrap(), 20);
267///
268/// // Modify in place
269/// let mut v = array![1, 2];
270/// v.as_array_mut().unwrap().push(3.into());
271/// assert_eq!(v.as_array().unwrap().len(), 3);
272/// ```
273///
274/// ## Maps
275///
276/// Maps are stored as `BTreeMap<Value, Value>`, giving canonical key
277/// order. Use standard `BTreeMap` methods on the result of
278/// [`as_map`](Self::as_map) to look up entries.
279///
280/// | Method | Returns |
281/// |---|---|
282/// | [`as_map`](Self::as_map) | `Result<&BTreeMap<Value, Value>>` |
283/// | [`as_map_mut`](Self::as_map_mut) | `Result<&mut BTreeMap<Value, Value>>` |
284/// | [`into_map`](Self::into_map) | `Result<BTreeMap<Value, Value>>` |
285///
286/// ```
287/// use cbor_core::{Value, map};
288///
289/// let v = map! { "name" => "Alice", "age" => 30 };
290/// let name = &v.as_map().unwrap()[&"name".into()];
291/// assert_eq!(name.as_str().unwrap(), "Alice");
292///
293/// // Modify in place
294/// let mut v = map! { "count" => 1 };
295/// v.as_map_mut().unwrap().insert("count".into(), 2.into());
296/// assert_eq!(v.as_map().unwrap()[&"count".into()].to_u32().unwrap(), 2);
297/// ```
298///
299/// ## Indexing
300///
301/// Arrays and maps support `Index` and `IndexMut` with any type that
302/// converts into `Value`. For arrays the index is converted to `usize`;
303/// for maps it is used as a key lookup. Panics on type mismatch or
304/// missing key, just like `Vec` and `BTreeMap`.
305///
306/// ```
307/// use cbor_core::{Value, array, map};
308///
309/// let a = array![10, 20, 30];
310/// assert_eq!(a[1_u32].to_u32().unwrap(), 20);
311///
312/// let m = map! { "x" => 10, "y" => 20 };
313/// assert_eq!(m["x"].to_u32().unwrap(), 10);
314/// ```
315///
316/// ## Tags
317///
318/// A tag wraps another value with a numeric label (e.g. tag 1 for epoch
319/// timestamps, tag 32 for URIs). Tags can be nested.
320///
321/// | Method | Returns | Notes |
322/// |---|---|---|
323/// | [`tag_number`](Self::tag_number) | `Result<u64>` | Tag number |
324/// | [`tag_content`](Self::tag_content) | `Result<&Value>` | Borrowed content |
325/// | [`tag_content_mut`](Self::tag_content_mut) | `Result<&mut Value>` | Mutable content |
326/// | [`as_tag`](Self::as_tag) | `Result<(u64, &Value)>` | Both parts |
327/// | [`as_tag_mut`](Self::as_tag_mut) | `Result<(u64, &mut Value)>` | Mutable content |
328/// | [`into_tag`](Self::into_tag) | `Result<(u64, Value)>` | Consuming |
329///
330/// Use [`untagged`](Self::untagged) to look through tags without removing
331/// them, [`remove_tag`](Self::remove_tag) to strip the outermost tag, or
332/// [`remove_all_tags`](Self::remove_all_tags) to strip all layers at once.
333///
334/// ```
335/// use cbor_core::Value;
336///
337/// // Create a tagged value (tag 32 = URI)
338/// let mut uri = Value::tag(32, "https://example.com");
339///
340/// // Inspect
341/// let (tag_num, content) = uri.as_tag().unwrap();
342/// assert_eq!(tag_num, 32);
343/// assert_eq!(content.as_str().unwrap(), "https://example.com");
344///
345/// // Look through tags without removing them
346/// assert_eq!(uri.untagged().as_str().unwrap(), "https://example.com");
347///
348/// // Strip the tag in place
349/// let removed = uri.remove_tag();
350/// assert_eq!(removed, Some(32));
351/// assert_eq!(uri.as_str().unwrap(), "https://example.com");
352/// ```
353///
354/// Accessor methods see through tags transparently: calling `as_str()`
355/// on a tagged text string works without manually unwrapping the tag
356/// first. This applies to all accessors (`to_*`, `as_*`, `into_*`).
357///
358/// ```
359/// use cbor_core::Value;
360///
361/// let uri = Value::tag(32, "https://example.com");
362/// assert_eq!(uri.as_str().unwrap(), "https://example.com");
363///
364/// // Nested tags are also transparent
365/// let nested = Value::tag(100, Value::tag(200, 42_u32));
366/// assert_eq!(nested.to_u32().unwrap(), 42);
367/// ```
368///
369/// Big integers are internally represented as tagged byte strings
370/// (tags 2 and 3). The integer accessors recognise these tags and
371/// decode the bytes automatically, even when wrapped in additional
372/// custom tags. Byte-level accessors like `as_bytes()` also see
373/// through tags, so calling `as_bytes()` on a big integer returns
374/// the raw payload bytes.
375///
376/// If a tag is removed via `remove_tag`, `remove_all_tags`, or by
377/// consuming through `into_tag`, the value becomes a plain byte
378/// string and can no longer be read as an integer.
379///
380/// # Type introspection
381///
382/// [`data_type`](Self::data_type) returns a [`DataType`] enum for
383/// lightweight type checks without matching on the full enum.
384///
385/// ```
386/// use cbor_core::Value;
387///
388/// let v = Value::from(3.14_f64);
389/// assert!(v.data_type().is_float());
390/// ```
391#[derive(Debug, Clone)]
392pub enum Value {
393    /// Simple value such as `null`, `true`, or `false` (major type 7).
394    ///
395    /// In CBOR, booleans and null are simple values, not distinct types.
396    /// A `Value::from(true)` is stored as `SimpleValue(21)` and is
397    /// accessible through both [`to_bool`](Self::to_bool) and
398    /// [`to_simple_value`](Self::to_simple_value).
399    SimpleValue(SimpleValue),
400
401    /// Unsigned integer (major type 0). Stores values 0 through 2^64-1.
402    Unsigned(u64),
403
404    /// Negative integer (major type 1). The actual value is -1 - n,
405    /// covering -1 through -2^64.
406    Negative(u64),
407
408    /// IEEE 754 floating-point number (major type 7, additional info 25-27).
409    Float(Float),
410
411    /// Byte string (major type 2).
412    ByteString(Vec<u8>),
413
414    /// UTF-8 text string (major type 3).
415    TextString(String),
416
417    /// Array of data items (major type 4).
418    Array(Vec<Value>),
419
420    /// Map of key-value pairs in canonical order (major type 5).
421    Map(BTreeMap<Value, Value>),
422
423    /// Tagged data item (major type 6). The first field is the tag number,
424    /// the second is the enclosed content.
425    Tag(u64, Box<Value>),
426}
427
428impl Default for Value {
429    fn default() -> Self {
430        Self::null()
431    }
432}
433
434impl PartialEq for Value {
435    fn eq(&self, other: &Self) -> bool {
436        self.cmp(other) == cmp::Ordering::Equal
437    }
438}
439
440impl Eq for Value {}
441
442impl Ord for Value {
443    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
444        self.cbor_major()
445            .cmp(&other.cbor_major())
446            .then_with(|| self.cbor_argument().cmp(&other.cbor_argument()))
447            .then_with(|| match (self, other) {
448                (Self::TextString(a), Self::TextString(b)) => a.cmp(b),
449                (Self::ByteString(a), Self::ByteString(b)) => a.cmp(b),
450                (Self::Array(a), Self::Array(b)) => a.cmp(b),
451                (Self::Map(a), Self::Map(b)) => a.cmp(b),
452                (Self::Tag(_, a), Self::Tag(_, b)) => a.cmp(b),
453                _ => std::cmp::Ordering::Equal,
454            })
455    }
456}
457
458impl PartialOrd for Value {
459    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
460        Some(self.cmp(other))
461    }
462}
463
464impl Hash for Value {
465    fn hash<H: Hasher>(&self, state: &mut H) {
466        self.cbor_major().hash(state);
467        self.cbor_argument().hash(state);
468        match self {
469            Self::TextString(s) => s.hash(state),
470            Self::ByteString(b) => b.hash(state),
471            Self::Array(a) => a.hash(state),
472            Self::Map(m) => {
473                for (k, v) in m {
474                    k.hash(state);
475                    v.hash(state);
476                }
477            }
478            Self::Tag(_, v) => v.hash(state),
479            _ => {}
480        }
481    }
482}
483
484impl Value {
485    /// Take the value out, leaving `null` in its place.
486    ///
487    /// ```
488    /// use cbor_core::Value;
489    ///
490    /// let mut v = Value::from(42);
491    /// let taken = v.take();
492    /// assert_eq!(taken.to_u32().unwrap(), 42);
493    /// assert!(v.data_type().is_null());
494    /// ```
495    pub fn take(&mut self) -> Self {
496        std::mem::take(self)
497    }
498
499    /// Replace the value, returning the old one.
500    ///
501    /// ```
502    /// use cbor_core::Value;
503    ///
504    /// let mut v = Value::from("hello");
505    /// let old = v.replace(Value::from("world"));
506    /// assert_eq!(old.as_str().unwrap(), "hello");
507    /// assert_eq!(v.as_str().unwrap(), "world");
508    /// ```
509    pub fn replace(&mut self, value: Self) -> Self {
510        std::mem::replace(self, value)
511    }
512
513    /// Encode this value to binary CBOR bytes.
514    ///
515    /// This is a convenience wrapper around [`write_to`](Self::write_to).
516    ///
517    /// ```
518    /// use cbor_core::Value;
519    /// let bytes = Value::from(42_u32).encode();
520    /// assert_eq!(bytes, [0x18, 42]);
521    /// ```
522    #[must_use]
523    pub fn encode(&self) -> Vec<u8> {
524        let len = self.cbor_len();
525        let mut bytes = Vec::with_capacity(len);
526        self.write_to(&mut bytes).unwrap();
527        debug_assert_eq!(bytes.len(), len);
528        bytes
529    }
530
531    /// Encode this value to a hex-encoded CBOR string.
532    ///
533    /// This is a convenience wrapper around [`write_hex_to`](Self::write_hex_to).
534    ///
535    /// ```
536    /// use cbor_core::Value;
537    /// let hex = Value::from(42).encode_hex();
538    /// assert_eq!(hex, "182a");
539    /// ```
540    #[must_use]
541    pub fn encode_hex(&self) -> String {
542        let len2 = self.cbor_len() * 2;
543        let mut hex = Vec::with_capacity(len2);
544        self.write_hex_to(&mut hex).unwrap();
545        debug_assert_eq!(hex.len(), len2);
546        String::from_utf8(hex).unwrap()
547    }
548
549    /// Decode a CBOR data item from binary bytes.
550    ///
551    /// Accepts any byte source (`&[u8]`, `&str`, `String`, `Vec<u8>`, etc.).
552    /// Returns `Err` if the encoding is not canonical.
553    ///
554    /// This is a convenience wrapper around [`read_from`](Self::read_from).
555    ///
556    /// ```
557    /// use cbor_core::Value;
558    /// let v = Value::decode(&[0x18, 42]).unwrap();
559    /// assert_eq!(v.to_u32().unwrap(), 42);
560    /// ```
561    pub fn decode(bytes: impl AsRef<[u8]>) -> Result<Self> {
562        let mut bytes = bytes.as_ref();
563        Self::read_from(&mut bytes)
564    }
565
566    /// Decode a CBOR data item from hex-encoded bytes.
567    ///
568    /// Accepts any byte source (`&[u8]`, `&str`, `String`, `Vec<u8>`, etc.).
569    /// Both uppercase and lowercase hex digits are accepted.
570    /// Returns `Err` if the encoding is not canonical.
571    ///
572    /// This is a convenience wrapper around [`read_hex_from`](Self::read_hex_from).
573    ///
574    /// ```
575    /// use cbor_core::Value;
576    /// let v = Value::decode_hex("182a").unwrap();
577    /// assert_eq!(v.to_u32().unwrap(), 42);
578    /// ```
579    pub fn decode_hex(hex: impl AsRef<[u8]>) -> Result<Self> {
580        let mut bytes = hex.as_ref();
581        Self::read_hex_from(&mut bytes)
582    }
583
584    /// Read a single CBOR data item from a binary stream.
585    ///
586    /// ```
587    /// use cbor_core::Value;
588    /// let mut bytes: &[u8] = &[0x18, 42];
589    /// let v = Value::read_from(&mut bytes).unwrap();
590    /// assert_eq!(v.to_u32().unwrap(), 42);
591    /// ```
592    pub fn read_from(reader: &mut impl io::Read) -> Result<Self> {
593        let ctrl_byte = {
594            let mut buf = [0];
595            reader.read_exact(&mut buf)?;
596            buf[0]
597        };
598
599        let is_float = matches!(ctrl_byte, CtrlByte::F16 | CtrlByte::F32 | CtrlByte::F64);
600
601        let major = ctrl_byte >> 5;
602        let info = ctrl_byte & 0x1f;
603
604        let argument = {
605            let mut buf = [0; 8];
606
607            if info < ArgLength::U8 {
608                buf[7] = info;
609            } else {
610                match info {
611                    ArgLength::U8 => reader.read_exact(&mut buf[7..])?,
612                    ArgLength::U16 => reader.read_exact(&mut buf[6..])?,
613                    ArgLength::U32 => reader.read_exact(&mut buf[4..])?,
614                    ArgLength::U64 => reader.read_exact(&mut buf)?,
615                    _ => return Err(Error::InvalidEncoding),
616                }
617            }
618
619            u64::from_be_bytes(buf)
620        };
621
622        if !is_float {
623            let non_deterministic = match info {
624                ArgLength::U8 => argument < ArgLength::U8.into(),
625                ArgLength::U16 => argument <= u8::MAX.into(),
626                ArgLength::U32 => argument <= u16::MAX.into(),
627                ArgLength::U64 => argument <= u32::MAX.into(),
628                _ => false,
629            };
630
631            if non_deterministic {
632                return Err(Error::InvalidEncoding);
633            }
634        }
635
636        let this = match major {
637            Major::UNSIGNED => Self::Unsigned(argument),
638            Major::NEGATIVE => Self::Negative(argument),
639
640            Major::BYTE_STRING => Self::ByteString(read_vec(reader, argument)?),
641
642            Major::TEXT_STRING => {
643                let bytes = read_vec(reader, argument)?;
644                let string = String::from_utf8(bytes).map_err(|_| Error::InvalidUtf8)?;
645                Self::TextString(string)
646            }
647
648            Major::ARRAY => {
649                let mut vec = Vec::with_capacity(argument.try_into().unwrap());
650                for _ in 0..argument {
651                    vec.push(Self::read_from(reader)?);
652                }
653                Self::Array(vec)
654            }
655
656            Major::MAP => {
657                let mut map = BTreeMap::new();
658                let mut prev = None;
659
660                for _ in 0..argument {
661                    let key = Self::read_from(reader)?;
662                    let value = Self::read_from(reader)?;
663
664                    if let Some((prev_key, prev_value)) = prev.take() {
665                        if prev_key >= key {
666                            return Err(Error::InvalidEncoding);
667                        }
668                        map.insert(prev_key, prev_value);
669                    }
670
671                    prev = Some((key, value));
672                }
673
674                if let Some((key, value)) = prev.take() {
675                    map.insert(key, value);
676                }
677
678                Self::Map(map)
679            }
680
681            Major::TAG => {
682                let content = Box::new(Self::read_from(reader)?);
683
684                if matches!(argument, Tag::POS_BIG_INT | Tag::NEG_BIG_INT)
685                    && let Ok(bigint) = content.as_bytes()
686                {
687                    let valid = bigint.len() >= 8 && bigint[0] != 0;
688                    if !valid {
689                        return Err(Error::InvalidEncoding);
690                    }
691                }
692
693                Self::Tag(argument, content)
694            }
695
696            Major::SIMPLE_VALUE => match info {
697                0..=ArgLength::U8 => SimpleValue::from_u8(argument as u8)
698                    .map(Self::SimpleValue)
699                    .map_err(|_| Error::InvalidEncoding)?,
700
701                ArgLength::U16 => Self::Float(Float::from_u16(argument as u16)),
702                ArgLength::U32 => Self::Float(Float::from_u32(argument as u32)?),
703                ArgLength::U64 => Self::Float(Float::from_u64(argument)?),
704
705                _ => return Err(Error::InvalidEncoding),
706            },
707
708            _ => unreachable!(),
709        };
710
711        Ok(this)
712    }
713
714    /// Read a single CBOR data item from a hex-encoded stream.
715    ///
716    /// Each byte of CBOR is expected as two hex digits (uppercase or
717    /// lowercase).
718    ///
719    /// ```
720    /// use cbor_core::Value;
721    /// let mut hex = "182a".as_bytes();
722    /// let v = Value::read_hex_from(&mut hex).unwrap();
723    /// assert_eq!(v.to_u32().unwrap(), 42);
724    /// ```
725    pub fn read_hex_from(reader: impl io::Read) -> Result<Self> {
726        struct HexReader<R>(R);
727
728        impl<R: io::Read> io::Read for HexReader<R> {
729            fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
730                fn nibble(char: u8) -> io::Result<u8> {
731                    match char {
732                        b'0'..=b'9' => Ok(char - b'0'),
733                        b'a'..=b'f' => Ok(char - b'a' + 10),
734                        b'A'..=b'F' => Ok(char - b'A' + 10),
735                        _ => Err(io::ErrorKind::InvalidData.into()),
736                    }
737                }
738
739                for byte in buf.iter_mut() {
740                    let mut hex = [0; 2];
741                    self.0.read_exact(&mut hex)?;
742                    *byte = nibble(hex[0])? << 4 | nibble(hex[1])?;
743                }
744
745                Ok(buf.len())
746            }
747        }
748
749        Self::read_from(&mut HexReader(reader))
750    }
751
752    /// Write this value as binary CBOR to a stream.
753    ///
754    /// ```
755    /// use cbor_core::Value;
756    /// let mut buf = Vec::new();
757    /// Value::from(42_u32).write_to(&mut buf).unwrap();
758    /// assert_eq!(buf, [0x18, 42]);
759    /// ```
760    pub fn write_to(&self, writer: &mut impl io::Write) -> Result<()> {
761        let major = self.cbor_major();
762        let (info, argument) = self.cbor_argument();
763
764        let ctrl_byte = major << 5 | info;
765        writer.write_all(&[ctrl_byte])?;
766
767        let buf = argument.to_be_bytes();
768        match info {
769            ArgLength::U8 => writer.write_all(&buf[7..])?,
770            ArgLength::U16 => writer.write_all(&buf[6..])?,
771            ArgLength::U32 => writer.write_all(&buf[4..])?,
772            ArgLength::U64 => writer.write_all(&buf)?,
773            _ => (), // argument embedded in ctrl byte
774        }
775
776        match self {
777            Value::ByteString(bytes) => writer.write_all(bytes)?,
778            Value::TextString(string) => writer.write_all(string.as_bytes())?,
779
780            Value::Tag(_number, content) => content.write_to(writer)?,
781
782            Value::Array(values) => {
783                for value in values {
784                    value.write_to(writer)?;
785                }
786            }
787
788            Value::Map(map) => {
789                for (key, value) in map {
790                    key.write_to(writer)?;
791                    value.write_to(writer)?;
792                }
793            }
794
795            _ => (),
796        }
797
798        Ok(())
799    }
800
801    /// Write this value as hex-encoded CBOR to a stream.
802    ///
803    /// Each binary byte is written as two lowercase hex digits. The
804    /// adapter encodes on the fly without buffering the full output.
805    ///
806    /// ```
807    /// use cbor_core::Value;
808    /// let mut buf = Vec::new();
809    /// Value::from(42_u32).write_hex_to(&mut buf).unwrap();
810    /// assert_eq!(buf, b"182a");
811    /// ```
812    pub fn write_hex_to(&self, writer: impl io::Write) -> Result<()> {
813        struct HexWriter<W>(W);
814
815        impl<W: io::Write> io::Write for HexWriter<W> {
816            fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
817                for &byte in buf {
818                    write!(self.0, "{byte:02x}")?;
819                }
820                Ok(buf.len())
821            }
822            fn flush(&mut self) -> io::Result<()> {
823                Ok(())
824            }
825        }
826
827        self.write_to(&mut HexWriter(writer))
828    }
829
830    fn cbor_major(&self) -> u8 {
831        match self {
832            Value::Unsigned(_) => Major::UNSIGNED,
833            Value::Negative(_) => Major::NEGATIVE,
834            Value::ByteString(_) => Major::BYTE_STRING,
835            Value::TextString(_) => Major::TEXT_STRING,
836            Value::Array(_) => Major::ARRAY,
837            Value::Map(_) => Major::MAP,
838            Value::Tag(_, _) => Major::TAG,
839            Value::SimpleValue(_) => Major::SIMPLE_VALUE,
840            Value::Float(_) => Major::SIMPLE_VALUE,
841        }
842    }
843
844    fn cbor_argument(&self) -> (u8, u64) {
845        fn arg(value: u64) -> (u8, u64) {
846            if value < ArgLength::U8.into() {
847                (value as u8, value)
848            } else {
849                let info = match value {
850                    0x00..=0xFF => ArgLength::U8,
851                    0x100..=0xFFFF => ArgLength::U16,
852                    0x10000..=0xFFFF_FFFF => ArgLength::U32,
853                    _ => ArgLength::U64,
854                };
855                (info, value)
856            }
857        }
858
859        match self {
860            Value::Unsigned(value) => arg(*value),
861            Value::Negative(value) => arg(*value),
862            Value::ByteString(vec) => arg(vec.len().try_into().unwrap()),
863            Value::TextString(str) => arg(str.len().try_into().unwrap()),
864            Value::Array(vec) => arg(vec.len().try_into().unwrap()),
865            Value::Map(map) => arg(map.len().try_into().unwrap()),
866            Value::Tag(number, _) => arg(*number),
867            Value::SimpleValue(value) => arg(value.0.into()),
868            Value::Float(float) => float.cbor_argument(),
869        }
870    }
871
872    /// Encoded length
873    fn cbor_len(&self) -> usize {
874        let (info, _) = self.cbor_argument();
875
876        let header_len = match info {
877            0..ArgLength::U8 => 1,
878            ArgLength::U8 => 2,
879            ArgLength::U16 => 3,
880            ArgLength::U32 => 5,
881            ArgLength::U64 => 9,
882            _ => unreachable!(),
883        };
884
885        let data_len = match self {
886            Self::ByteString(bytes) => bytes.len(),
887            Self::TextString(text) => text.len(),
888            Self::Array(vec) => vec.iter().map(Self::cbor_len).sum(),
889            Self::Map(map) => map.iter().map(|(k, v)| k.cbor_len() + v.cbor_len()).sum(),
890            Self::Tag(_, content) => content.cbor_len(),
891            _ => 0,
892        };
893
894        header_len + data_len
895    }
896
897    // ------------------- constructors -------------------
898
899    /// Create a CBOR null value.
900    #[must_use]
901    pub const fn null() -> Self {
902        Self::SimpleValue(SimpleValue::NULL)
903    }
904
905    /// Create a CBOR simple value.
906    ///
907    /// # Panics
908    ///
909    /// Panics if the value is in the reserved range 24-31.
910    /// Use [`SimpleValue::from_u8`] for a fallible alternative.
911    pub fn simple_value(value: impl TryInto<SimpleValue>) -> Self {
912        match value.try_into() {
913            Ok(sv) => Self::SimpleValue(sv),
914            Err(_) => panic!("Invalid simple value"),
915        }
916    }
917
918    /// Create a CBOR float.
919    ///
920    /// Via the [`Float`] type floats can be created out of integers and booleans too.
921    ///
922    /// ```
923    /// use cbor_core::Value;
924    ///
925    /// let f1 = Value::float(1.0);
926    /// assert!(f1.to_f64() == Ok(1.0));
927    ///
928    /// let f2 = Value::float(2_u32);
929    /// assert!(f2.to_f64() == Ok(2.0));
930    ///
931    /// let f3 = Value::float(true);
932    /// assert!(f3.to_f64() == Ok(1.0));
933    /// ```
934    ///
935    /// The value is stored in the shortest IEEE 754 form (f16, f32,
936    /// or f64) that preserves it exactly.
937    pub fn float(value: impl Into<Float>) -> Self {
938        Self::Float(value.into())
939    }
940
941    /// Create a CBOR array from a `Vec`, slice, or fixed-size array.
942    pub fn array(array: impl Into<Array>) -> Self {
943        Self::Array(array.into().0)
944    }
945
946    /// Create a CBOR map. Keys are stored in canonical order.
947    pub fn map(map: impl Into<Map>) -> Self {
948        Self::Map(map.into().0)
949    }
950
951    /// Wrap a value with a CBOR tag.
952    ///
953    /// ```
954    /// use cbor_core::Value;
955    /// let uri = Value::tag(32, "https://example.com");
956    /// assert_eq!(uri.tag_number().unwrap(), 32);
957    /// ```
958    pub fn tag(number: u64, content: impl Into<Value>) -> Self {
959        Self::Tag(number, Box::new(content.into()))
960    }
961
962    /// Return the [`DataType`] of this value for type-level dispatch.
963    #[must_use]
964    pub const fn data_type(&self) -> DataType {
965        match self {
966            Self::SimpleValue(sv) => sv.data_type(),
967
968            Self::Unsigned(_) | Self::Negative(_) => DataType::Int,
969
970            Self::Float(float) => float.data_type(),
971
972            Self::TextString(_) => DataType::Text,
973            Self::ByteString(_) => DataType::Bytes,
974
975            Self::Array(_) => DataType::Array,
976            Self::Map(_) => DataType::Map,
977
978            Self::Tag(Tag::POS_BIG_INT | Tag::NEG_BIG_INT, content) if content.data_type().is_bytes() => {
979                DataType::BigInt
980            }
981            Self::Tag(_, _) => DataType::Tag,
982        }
983    }
984
985    /// Internal shortcut helper
986    const fn is_bytes(&self) -> bool {
987        self.data_type().is_bytes()
988    }
989
990    /// Extract a boolean. Returns `Err` for non-boolean values.
991    pub const fn to_bool(&self) -> Result<bool> {
992        match self {
993            Self::SimpleValue(sv) => sv.to_bool(),
994            Self::Tag(_number, content) => content.untagged().to_bool(),
995            _ => Err(Error::IncompatibleType),
996        }
997    }
998
999    /// Extract the raw simple value number (0-255, excluding 24-31).
1000    pub const fn to_simple_value(&self) -> Result<u8> {
1001        match self {
1002            Self::SimpleValue(sv) => Ok(sv.0),
1003            Self::Tag(_number, content) => content.untagged().to_simple_value(),
1004            _ => Err(Error::IncompatibleType),
1005        }
1006    }
1007
1008    /// Narrow to `u8`. Returns `Err(Overflow)` or `Err(NegativeUnsigned)` on mismatch.
1009    pub const fn to_u8(&self) -> Result<u8> {
1010        match self {
1011            Self::Unsigned(x) if *x <= u8::MAX as u64 => Ok(*x as u8),
1012            Self::Unsigned(_) => Err(Error::Overflow),
1013            Self::Negative(_) => Err(Error::NegativeUnsigned),
1014            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1015            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::NegativeUnsigned),
1016            Self::Tag(_other_number, content) => content.peeled().to_u8(),
1017            _ => Err(Error::IncompatibleType),
1018        }
1019    }
1020
1021    /// Narrow to `u16`.
1022    pub const fn to_u16(&self) -> Result<u16> {
1023        match self {
1024            Self::Unsigned(x) if *x <= u16::MAX as u64 => Ok(*x as u16),
1025            Self::Unsigned(_) => Err(Error::Overflow),
1026            Self::Negative(_) => Err(Error::NegativeUnsigned),
1027            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1028            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::NegativeUnsigned),
1029            Self::Tag(_other_number, content) => content.peeled().to_u16(),
1030            _ => Err(Error::IncompatibleType),
1031        }
1032    }
1033
1034    /// Narrow to `u32`.
1035    pub const fn to_u32(&self) -> Result<u32> {
1036        match self {
1037            Self::Unsigned(x) if *x <= u32::MAX as u64 => Ok(*x as u32),
1038            Self::Unsigned(_) => Err(Error::Overflow),
1039            Self::Negative(_) => Err(Error::NegativeUnsigned),
1040            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1041            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::NegativeUnsigned),
1042            Self::Tag(_other_number, content) => content.peeled().to_u32(),
1043            _ => Err(Error::IncompatibleType),
1044        }
1045    }
1046
1047    /// Narrow to `u64`.
1048    pub const fn to_u64(&self) -> Result<u64> {
1049        match self {
1050            Self::Unsigned(x) => Ok(*x),
1051            Self::Negative(_) => Err(Error::NegativeUnsigned),
1052            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1053            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::NegativeUnsigned),
1054            Self::Tag(_other_number, content) => content.peeled().to_u64(),
1055            _ => Err(Error::IncompatibleType),
1056        }
1057    }
1058
1059    /// Narrow to `u128`. Handles big integers (tag 2) transparently.
1060    pub fn to_u128(&self) -> Result<u128> {
1061        match self {
1062            Self::Unsigned(x) => Ok(*x as u128),
1063            Self::Negative(_) => Err(Error::NegativeUnsigned),
1064            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => u128_from_bytes(content.as_bytes()?),
1065            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::NegativeUnsigned),
1066            Self::Tag(_other_number, content) => content.peeled().to_u128(),
1067            _ => Err(Error::IncompatibleType),
1068        }
1069    }
1070
1071    /// Narrow to `usize`.
1072    #[cfg(target_pointer_width = "32")]
1073    pub const fn to_usize(&self) -> Result<usize> {
1074        match self {
1075            Self::Unsigned(x) if *x <= u32::MAX as u64 => Ok(*x as usize),
1076            Self::Unsigned(_) => Err(Error::Overflow),
1077            Self::Negative(_) => Err(Error::NegativeUnsigned),
1078            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1079            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::NegativeUnsigned),
1080            Self::Tag(_other_number, content) => content.peeled().to_usize(),
1081            _ => Err(Error::IncompatibleType),
1082        }
1083    }
1084
1085    /// Narrow to `usize`.
1086    #[cfg(target_pointer_width = "64")]
1087    pub const fn to_usize(&self) -> Result<usize> {
1088        match self {
1089            Self::Unsigned(x) => Ok(*x as usize),
1090            Self::Negative(_) => Err(Error::NegativeUnsigned),
1091            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1092            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::NegativeUnsigned),
1093            Self::Tag(_other_number, content) => content.peeled().to_usize(),
1094            _ => Err(Error::IncompatibleType),
1095        }
1096    }
1097
1098    /// Narrow to `i8`.
1099    pub const fn to_i8(&self) -> Result<i8> {
1100        match self {
1101            Self::Unsigned(x) if *x <= i8::MAX as u64 => Ok(*x as i8),
1102            Self::Unsigned(_) => Err(Error::Overflow),
1103            Self::Negative(x) if *x <= i8::MAX as u64 => Ok((!*x) as i8),
1104            Self::Negative(_) => Err(Error::Overflow),
1105            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1106            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1107            Self::Tag(_other_number, content) => content.peeled().to_i8(),
1108            _ => Err(Error::IncompatibleType),
1109        }
1110    }
1111
1112    /// Narrow to `i16`.
1113    pub const fn to_i16(&self) -> Result<i16> {
1114        match self {
1115            Self::Unsigned(x) if *x <= i16::MAX as u64 => Ok(*x as i16),
1116            Self::Unsigned(_) => Err(Error::Overflow),
1117            Self::Negative(x) if *x <= i16::MAX as u64 => Ok((!*x) as i16),
1118            Self::Negative(_) => Err(Error::Overflow),
1119            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1120            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1121            Self::Tag(_other_number, content) => content.peeled().to_i16(),
1122            _ => Err(Error::IncompatibleType),
1123        }
1124    }
1125
1126    /// Narrow to `i32`.
1127    pub const fn to_i32(&self) -> Result<i32> {
1128        match self {
1129            Self::Unsigned(x) if *x <= i32::MAX as u64 => Ok(*x as i32),
1130            Self::Unsigned(_) => Err(Error::Overflow),
1131            Self::Negative(x) if *x <= i32::MAX as u64 => Ok((!*x) as i32),
1132            Self::Negative(_) => Err(Error::Overflow),
1133            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1134            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1135            Self::Tag(_other_number, content) => content.peeled().to_i32(),
1136            _ => Err(Error::IncompatibleType),
1137        }
1138    }
1139
1140    /// Narrow to `i64`.
1141    pub const fn to_i64(&self) -> Result<i64> {
1142        match self {
1143            Self::Unsigned(x) if *x <= i64::MAX as u64 => Ok(*x as i64),
1144            Self::Unsigned(_) => Err(Error::Overflow),
1145            Self::Negative(x) if *x <= i64::MAX as u64 => Ok((!*x) as i64),
1146            Self::Negative(_) => Err(Error::Overflow),
1147            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1148            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1149            Self::Tag(_other_number, content) => content.peeled().to_i64(),
1150            _ => Err(Error::IncompatibleType),
1151        }
1152    }
1153
1154    /// Narrow to `i128`. Handles big integers (tags 2 and 3) transparently.
1155    pub fn to_i128(&self) -> Result<i128> {
1156        match self {
1157            Self::Unsigned(x) => Ok(*x as i128),
1158            Self::Negative(x) => Ok(!(*x as i128)),
1159
1160            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => {
1161                let value = u128_from_bytes(content.as_bytes()?)?;
1162                if value <= i128::MAX as u128 {
1163                    Ok(value as i128)
1164                } else {
1165                    Err(Error::Overflow)
1166                }
1167            }
1168
1169            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => {
1170                let value = u128_from_bytes(content.as_bytes()?)?;
1171                if value <= i128::MAX as u128 {
1172                    Ok((!value) as i128)
1173                } else {
1174                    Err(Error::Overflow)
1175                }
1176            }
1177
1178            Self::Tag(_other_number, content) => content.peeled().to_i128(),
1179
1180            _ => Err(Error::IncompatibleType),
1181        }
1182    }
1183
1184    /// Narrow to `isize`.
1185    #[cfg(target_pointer_width = "32")]
1186    pub const fn to_isize_(&self) -> Result<isize> {
1187        match self {
1188            Self::Unsigned(x) if *x <= i32::MAX as u64 => Ok(*x as isize),
1189            Self::Unsigned(_) => Err(Error::Overflow),
1190            Self::Negative(x) if *x <= i32::MAX as u64 => Ok((!*x) as isize),
1191            Self::Negative(_) => Err(Error::Overflow),
1192            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1193            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1194            Self::Tag(_other_number, content) => content.peeled().to_isize(),
1195            _ => Err(Error::IncompatibleType),
1196        }
1197    }
1198
1199    /// Narrow to `isize`.
1200    #[cfg(target_pointer_width = "64")]
1201    pub const fn to_isize(&self) -> Result<isize> {
1202        match self {
1203            Self::Unsigned(x) if *x <= i64::MAX as u64 => Ok(*x as isize),
1204            Self::Unsigned(_) => Err(Error::Overflow),
1205            Self::Negative(x) if *x <= i64::MAX as u64 => Ok((!*x) as isize),
1206            Self::Negative(_) => Err(Error::Overflow),
1207            Self::Tag(Tag::POS_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1208            Self::Tag(Tag::NEG_BIG_INT, content) if content.is_bytes() => Err(Error::Overflow),
1209            Self::Tag(_other_number, content) => content.peeled().to_isize(),
1210            _ => Err(Error::IncompatibleType),
1211        }
1212    }
1213
1214    /// Convert to `f32`. Returns `Err(Precision)` for f64-width values.
1215    pub fn to_f32(&self) -> Result<f32> {
1216        match self {
1217            Self::Float(float) => float.to_f32(),
1218            Self::Tag(_number, content) => content.untagged().to_f32(),
1219            _ => Err(Error::IncompatibleType),
1220        }
1221    }
1222
1223    /// Convert to `f64`. Always succeeds for float values.
1224    pub fn to_f64(&self) -> Result<f64> {
1225        match self {
1226            Self::Float(float) => Ok(float.to_f64()),
1227            Self::Tag(_number, content) => content.untagged().to_f64(),
1228            _ => Err(Error::IncompatibleType),
1229        }
1230    }
1231
1232    /// Borrow the byte string as a slice.
1233    pub fn as_bytes(&self) -> Result<&[u8]> {
1234        match self {
1235            Self::ByteString(vec) => Ok(vec.as_slice()),
1236            Self::Tag(_number, content) => content.untagged().as_bytes(),
1237            _ => Err(Error::IncompatibleType),
1238        }
1239    }
1240
1241    /// Borrow the byte string as a mutable `Vec`.
1242    pub const fn as_bytes_mut(&mut self) -> Result<&mut Vec<u8>> {
1243        match self {
1244            Self::ByteString(vec) => Ok(vec),
1245            Self::Tag(_number, content) => content.untagged_mut().as_bytes_mut(),
1246            _ => Err(Error::IncompatibleType),
1247        }
1248    }
1249
1250    /// Take ownership of the byte string.
1251    pub fn into_bytes(self) -> Result<Vec<u8>> {
1252        match self {
1253            Self::ByteString(vec) => Ok(vec),
1254            Self::Tag(_number, content) => content.into_untagged().into_bytes(),
1255            _ => Err(Error::IncompatibleType),
1256        }
1257    }
1258
1259    /// Borrow the text string as a `&str`.
1260    pub fn as_str(&self) -> Result<&str> {
1261        match self {
1262            Self::TextString(s) => Ok(s.as_str()),
1263            Self::Tag(_number, content) => content.untagged().as_str(),
1264            _ => Err(Error::IncompatibleType),
1265        }
1266    }
1267
1268    /// Borrow the text string as a mutable `String`.
1269    pub const fn as_string_mut(&mut self) -> Result<&mut String> {
1270        match self {
1271            Self::TextString(s) => Ok(s),
1272            Self::Tag(_number, content) => content.untagged_mut().as_string_mut(),
1273            _ => Err(Error::IncompatibleType),
1274        }
1275    }
1276
1277    /// Take ownership of the text string.
1278    pub fn into_string(self) -> Result<String> {
1279        match self {
1280            Self::TextString(s) => Ok(s),
1281            Self::Tag(_number, content) => content.into_untagged().into_string(),
1282            _ => Err(Error::IncompatibleType),
1283        }
1284    }
1285
1286    /// Borrow the array elements as a slice.
1287    pub fn as_array(&self) -> Result<&[Value]> {
1288        match self {
1289            Self::Array(v) => Ok(v.as_slice()),
1290            Self::Tag(_number, content) => content.untagged().as_array(),
1291            _ => Err(Error::IncompatibleType),
1292        }
1293    }
1294
1295    /// Borrow the array as a mutable `Vec`.
1296    pub const fn as_array_mut(&mut self) -> Result<&mut Vec<Value>> {
1297        match self {
1298            Self::Array(v) => Ok(v),
1299            Self::Tag(_number, content) => content.untagged_mut().as_array_mut(),
1300            _ => Err(Error::IncompatibleType),
1301        }
1302    }
1303
1304    /// Take ownership of the array.
1305    pub fn into_array(self) -> Result<Vec<Value>> {
1306        match self {
1307            Self::Array(v) => Ok(v),
1308            Self::Tag(_number, content) => content.into_untagged().into_array(),
1309            _ => Err(Error::IncompatibleType),
1310        }
1311    }
1312
1313    /// Borrow the map.
1314    pub const fn as_map(&self) -> Result<&BTreeMap<Value, Value>> {
1315        match self {
1316            Self::Map(m) => Ok(m),
1317            Self::Tag(_number, content) => content.untagged().as_map(),
1318            _ => Err(Error::IncompatibleType),
1319        }
1320    }
1321
1322    /// Borrow the map mutably.
1323    pub const fn as_map_mut(&mut self) -> Result<&mut BTreeMap<Value, Value>> {
1324        match self {
1325            Self::Map(m) => Ok(m),
1326            Self::Tag(_number, content) => content.untagged_mut().as_map_mut(),
1327            _ => Err(Error::IncompatibleType),
1328        }
1329    }
1330
1331    /// Take ownership of the map.
1332    pub fn into_map(self) -> Result<BTreeMap<Value, Value>> {
1333        match self {
1334            Self::Map(m) => Ok(m),
1335            Self::Tag(_number, content) => content.into_untagged().into_map(),
1336            _ => Err(Error::IncompatibleType),
1337        }
1338    }
1339
1340    /// Return the tag number.
1341    pub const fn tag_number(&self) -> Result<u64> {
1342        match self {
1343            Self::Tag(number, _content) => Ok(*number),
1344            _ => Err(Error::IncompatibleType),
1345        }
1346    }
1347
1348    /// Borrow the tag content.
1349    pub const fn tag_content(&self) -> Result<&Self> {
1350        match self {
1351            Self::Tag(_tag, content) => Ok(content),
1352            _ => Err(Error::IncompatibleType),
1353        }
1354    }
1355
1356    /// Mutably borrow the tag content.
1357    pub const fn tag_content_mut(&mut self) -> Result<&mut Self> {
1358        match self {
1359            Self::Tag(_, value) => Ok(value),
1360            _ => Err(Error::IncompatibleType),
1361        }
1362    }
1363
1364    /// Borrow tag number and content together.
1365    pub fn as_tag(&self) -> Result<(u64, &Value)> {
1366        match self {
1367            Self::Tag(number, content) => Ok((*number, content)),
1368            _ => Err(Error::IncompatibleType),
1369        }
1370    }
1371
1372    /// Borrow tag number and mutable content together.
1373    pub fn as_tag_mut(&mut self) -> Result<(u64, &mut Value)> {
1374        match self {
1375            Self::Tag(number, content) => Ok((*number, content)),
1376            _ => Err(Error::IncompatibleType),
1377        }
1378    }
1379
1380    /// Consume self and return tag number and content.
1381    pub fn into_tag(self) -> Result<(u64, Value)> {
1382        match self {
1383            Self::Tag(number, content) => Ok((number, *content)),
1384            _ => Err(Error::IncompatibleType),
1385        }
1386    }
1387
1388    /// Remove the outermost tag, returning its number. Returns `None` if
1389    /// the value is not tagged.
1390    pub fn remove_tag(&mut self) -> Option<u64> {
1391        let mut result = None;
1392        if let Self::Tag(number, content) = self {
1393            result = Some(*number);
1394            *self = std::mem::take(content);
1395        }
1396        result
1397    }
1398
1399    /// Remove all nested tags, returning their numbers from outermost to
1400    /// innermost.
1401    pub fn remove_all_tags(&mut self) -> Vec<u64> {
1402        let mut tags = Vec::new();
1403        while let Self::Tag(number, content) = self {
1404            tags.push(*number);
1405            *self = std::mem::take(content);
1406        }
1407        tags
1408    }
1409
1410    /// Skip all tag wrappers except the innermost one.
1411    /// Returns `self` unchanged if not tagged or only single-tagged.
1412    #[must_use]
1413    const fn peeled(&self) -> &Self {
1414        let mut result = self;
1415        while let Self::Tag(_, content) = result
1416            && content.data_type().is_tag()
1417        {
1418            result = content;
1419        }
1420        result
1421    }
1422
1423    /// Borrow the innermost non-tag value, skipping all tag wrappers.
1424    #[must_use]
1425    pub const fn untagged(&self) -> &Self {
1426        let mut result = self;
1427        while let Self::Tag(_, content) = result {
1428            result = content;
1429        }
1430        result
1431    }
1432
1433    /// Mutable version of [`untagged`](Self::untagged).
1434    pub const fn untagged_mut(&mut self) -> &mut Self {
1435        let mut result = self;
1436        while let Self::Tag(_, content) = result {
1437            result = content;
1438        }
1439        result
1440    }
1441
1442    /// Consuming version of [`untagged`](Self::untagged).
1443    #[must_use]
1444    pub fn into_untagged(mut self) -> Self {
1445        while let Self::Tag(_number, content) = self {
1446            self = *content;
1447        }
1448        self
1449    }
1450}
1451
1452// --------- From-traits for Value ---------
1453
1454impl From<SimpleValue> for Value {
1455    fn from(value: SimpleValue) -> Self {
1456        Self::SimpleValue(value)
1457    }
1458}
1459
1460impl From<bool> for Value {
1461    fn from(value: bool) -> Self {
1462        Self::SimpleValue(SimpleValue::from_bool(value))
1463    }
1464}
1465
1466impl From<Integer> for Value {
1467    fn from(value: Integer) -> Self {
1468        value.into_value()
1469    }
1470}
1471
1472impl From<u8> for Value {
1473    fn from(value: u8) -> Self {
1474        Integer::from(value).into_value()
1475    }
1476}
1477
1478impl From<u16> for Value {
1479    fn from(value: u16) -> Self {
1480        Integer::from(value).into_value()
1481    }
1482}
1483
1484impl From<u32> for Value {
1485    fn from(value: u32) -> Self {
1486        Integer::from(value).into_value()
1487    }
1488}
1489
1490impl From<u64> for Value {
1491    fn from(value: u64) -> Self {
1492        Integer::from(value).into_value()
1493    }
1494}
1495
1496impl From<u128> for Value {
1497    fn from(value: u128) -> Self {
1498        Integer::from(value).into_value()
1499    }
1500}
1501
1502impl From<usize> for Value {
1503    fn from(value: usize) -> Self {
1504        Integer::from(value).into_value()
1505    }
1506}
1507
1508impl From<i8> for Value {
1509    fn from(value: i8) -> Self {
1510        Integer::from(value).into_value()
1511    }
1512}
1513
1514impl From<i16> for Value {
1515    fn from(value: i16) -> Self {
1516        Integer::from(value).into_value()
1517    }
1518}
1519
1520impl From<i32> for Value {
1521    fn from(value: i32) -> Self {
1522        Integer::from(value).into_value()
1523    }
1524}
1525
1526impl From<i64> for Value {
1527    fn from(value: i64) -> Self {
1528        Integer::from(value).into_value()
1529    }
1530}
1531
1532impl From<i128> for Value {
1533    fn from(value: i128) -> Self {
1534        Integer::from(value).into_value()
1535    }
1536}
1537
1538impl From<isize> for Value {
1539    fn from(value: isize) -> Self {
1540        Integer::from(value).into_value()
1541    }
1542}
1543
1544// --- Floats ---
1545
1546impl From<Float> for Value {
1547    fn from(value: Float) -> Self {
1548        Self::Float(value)
1549    }
1550}
1551
1552impl From<f32> for Value {
1553    fn from(value: f32) -> Self {
1554        Self::Float(value.into())
1555    }
1556}
1557
1558impl From<f64> for Value {
1559    fn from(value: f64) -> Self {
1560        Self::Float(value.into())
1561    }
1562}
1563
1564// --- Strings: String, str, Box ---
1565
1566impl From<&str> for Value {
1567    fn from(value: &str) -> Self {
1568        Self::TextString(value.into())
1569    }
1570}
1571
1572impl From<String> for Value {
1573    fn from(value: String) -> Self {
1574        Self::TextString(value)
1575    }
1576}
1577
1578impl From<&String> for Value {
1579    fn from(value: &String) -> Self {
1580        Self::TextString(value.clone())
1581    }
1582}
1583
1584impl From<Box<str>> for Value {
1585    fn from(value: Box<str>) -> Self {
1586        Self::TextString(value.into())
1587    }
1588}
1589
1590// --- ByteString: Vec, slice, array, Box ---
1591
1592impl From<Vec<u8>> for Value {
1593    fn from(value: Vec<u8>) -> Self {
1594        Self::ByteString(value)
1595    }
1596}
1597
1598impl From<&[u8]> for Value {
1599    fn from(value: &[u8]) -> Self {
1600        Self::ByteString(value.to_vec())
1601    }
1602}
1603
1604impl<const N: usize> From<[u8; N]> for Value {
1605    fn from(value: [u8; N]) -> Self {
1606        Self::ByteString(value.to_vec())
1607    }
1608}
1609
1610impl<const N: usize> From<&[u8; N]> for Value {
1611    fn from(value: &[u8; N]) -> Self {
1612        Self::ByteString(value.to_vec())
1613    }
1614}
1615
1616impl From<Box<[u8]>> for Value {
1617    fn from(value: Box<[u8]>) -> Self {
1618        Self::ByteString(Vec::from(value))
1619    }
1620}
1621
1622// --- Array of values: Vec, array, Box ---
1623
1624impl From<Vec<Value>> for Value {
1625    fn from(value: Vec<Value>) -> Self {
1626        Self::Array(value)
1627    }
1628}
1629
1630impl<const N: usize> From<[Value; N]> for Value {
1631    fn from(value: [Value; N]) -> Self {
1632        Self::Array(value.to_vec())
1633    }
1634}
1635
1636impl From<Box<[Value]>> for Value {
1637    fn from(value: Box<[Value]>) -> Self {
1638        Self::Array(value.to_vec())
1639    }
1640}
1641
1642// --- Array, Map, BTreeMap ---
1643
1644impl From<Array> for Value {
1645    fn from(value: Array) -> Self {
1646        Self::Array(value.into_inner())
1647    }
1648}
1649
1650impl From<Map> for Value {
1651    fn from(value: Map) -> Self {
1652        Self::Map(value.into_inner())
1653    }
1654}
1655
1656impl From<BTreeMap<Value, Value>> for Value {
1657    fn from(value: BTreeMap<Value, Value>) -> Self {
1658        Self::Map(value)
1659    }
1660}
1661
1662// --------- Index ---------
1663
1664impl<I: Into<Value>> Index<I> for Value {
1665    type Output = Value;
1666
1667    fn index(&self, index: I) -> &Value {
1668        let key = index.into();
1669        match self.untagged() {
1670            Value::Array(arr) => {
1671                let idx = key.to_usize().expect("array index must be a valid usize integer");
1672                &arr[idx]
1673            }
1674            Value::Map(map) => map.get(&key).expect("key not found in map"),
1675            _ => panic!("cannot index into {:?}", self.data_type()),
1676        }
1677    }
1678}
1679
1680impl<I: Into<Value>> IndexMut<I> for Value {
1681    fn index_mut(&mut self, index: I) -> &mut Value {
1682        let key = index.into();
1683        let data_type = self.untagged().data_type();
1684        match self.untagged_mut() {
1685            Value::Array(arr) => {
1686                let idx = key.to_usize().expect("array index must be a valid usize integer");
1687                &mut arr[idx]
1688            }
1689            Value::Map(map) => map.get_mut(&key).expect("key not found in map"),
1690            _ => panic!("cannot index into {:?}", data_type),
1691        }
1692    }
1693}
1694
1695// --------- TryFrom Value ---------
1696
1697impl TryFrom<Value> for bool {
1698    type Error = Error;
1699    fn try_from(value: Value) -> Result<Self> {
1700        value.to_bool()
1701    }
1702}
1703
1704impl TryFrom<Value> for SimpleValue {
1705    type Error = Error;
1706    fn try_from(value: Value) -> Result<Self> {
1707        match value {
1708            Value::SimpleValue(sv) => Ok(sv),
1709            _ => Err(Error::IncompatibleType),
1710        }
1711    }
1712}
1713
1714impl TryFrom<Value> for u8 {
1715    type Error = Error;
1716    fn try_from(value: Value) -> Result<Self> {
1717        value.to_u8()
1718    }
1719}
1720
1721impl TryFrom<Value> for u16 {
1722    type Error = Error;
1723    fn try_from(value: Value) -> Result<Self> {
1724        value.to_u16()
1725    }
1726}
1727
1728impl TryFrom<Value> for u32 {
1729    type Error = Error;
1730    fn try_from(value: Value) -> Result<Self> {
1731        value.to_u32()
1732    }
1733}
1734
1735impl TryFrom<Value> for u64 {
1736    type Error = Error;
1737    fn try_from(value: Value) -> Result<Self> {
1738        value.to_u64()
1739    }
1740}
1741
1742impl TryFrom<Value> for u128 {
1743    type Error = Error;
1744    fn try_from(value: Value) -> Result<Self> {
1745        value.to_u128()
1746    }
1747}
1748
1749impl TryFrom<Value> for usize {
1750    type Error = Error;
1751    fn try_from(value: Value) -> Result<Self> {
1752        value.to_usize()
1753    }
1754}
1755
1756impl TryFrom<Value> for i8 {
1757    type Error = Error;
1758    fn try_from(value: Value) -> Result<Self> {
1759        value.to_i8()
1760    }
1761}
1762
1763impl TryFrom<Value> for i16 {
1764    type Error = Error;
1765    fn try_from(value: Value) -> Result<Self> {
1766        value.to_i16()
1767    }
1768}
1769
1770impl TryFrom<Value> for i32 {
1771    type Error = Error;
1772    fn try_from(value: Value) -> Result<Self> {
1773        value.to_i32()
1774    }
1775}
1776
1777impl TryFrom<Value> for i64 {
1778    type Error = Error;
1779    fn try_from(value: Value) -> Result<Self> {
1780        value.to_i64()
1781    }
1782}
1783
1784impl TryFrom<Value> for i128 {
1785    type Error = Error;
1786    fn try_from(value: Value) -> Result<Self> {
1787        value.to_i128()
1788    }
1789}
1790
1791impl TryFrom<Value> for isize {
1792    type Error = Error;
1793    fn try_from(value: Value) -> Result<Self> {
1794        value.to_isize()
1795    }
1796}
1797
1798impl TryFrom<Value> for f32 {
1799    type Error = Error;
1800    fn try_from(value: Value) -> Result<Self> {
1801        value.to_f32()
1802    }
1803}
1804
1805impl TryFrom<Value> for f64 {
1806    type Error = Error;
1807    fn try_from(value: Value) -> Result<Self> {
1808        value.to_f64()
1809    }
1810}
1811
1812impl TryFrom<Value> for Float {
1813    type Error = Error;
1814    fn try_from(value: Value) -> Result<Self> {
1815        match value {
1816            Value::Float(f) => Ok(f),
1817            _ => Err(Error::IncompatibleType),
1818        }
1819    }
1820}
1821
1822impl TryFrom<Value> for Integer {
1823    type Error = Error;
1824    fn try_from(value: Value) -> Result<Self> {
1825        Integer::from_value(value)
1826    }
1827}
1828
1829impl TryFrom<Value> for String {
1830    type Error = Error;
1831    fn try_from(value: Value) -> Result<Self> {
1832        value.into_string()
1833    }
1834}
1835
1836impl TryFrom<Value> for Vec<u8> {
1837    type Error = Error;
1838    fn try_from(value: Value) -> Result<Self> {
1839        value.into_bytes()
1840    }
1841}
1842
1843impl TryFrom<Value> for Vec<Value> {
1844    type Error = Error;
1845    fn try_from(value: Value) -> Result<Self> {
1846        value.into_array()
1847    }
1848}
1849
1850impl TryFrom<Value> for BTreeMap<Value, Value> {
1851    type Error = Error;
1852    fn try_from(value: Value) -> Result<Self> {
1853        value.into_map()
1854    }
1855}
1856
1857impl TryFrom<Value> for Array {
1858    type Error = Error;
1859    fn try_from(value: Value) -> Result<Self> {
1860        value.into_array().map(Array::from)
1861    }
1862}
1863
1864impl TryFrom<Value> for Map {
1865    type Error = Error;
1866    fn try_from(value: Value) -> Result<Self> {
1867        value.into_map().map(Map::from)
1868    }
1869}