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>),
}Expand description
A single CBOR data item.
Value covers all CBOR major types: integers, floats, byte and text
strings, arrays, maps, tagged values, and simple values (null, booleans).
It encodes deterministically and decodes only canonical input.
§Creating values
Rust primitives convert via From:
use cbor_core::Value;
let n = Value::from(42_u32);
let s = Value::from("hello");
let b = Value::from(true);For arrays and maps the array! and map! macros are convenient:
use cbor_core::{Value, array, map};
let a = array![1, 2, 3];
let m = map! { "x" => 10, "y" => 20 };Arrays and maps can also be built from standard Rust collections.
Slices, Vecs, fixed-size arrays, BTreeMaps, HashMaps, and
slices of key-value pairs all convert automatically:
use cbor_core::Value;
use std::collections::HashMap;
// Array from a slice
let a = Value::array([1_u32, 2, 3].as_slice());
// Map from a HashMap
let mut hm = HashMap::new();
hm.insert(1_u32, 2_u32);
let m = Value::map(&hm);
// Map from key-value pairs
let m = Value::map([("x", 10), ("y", 20)]);Use () to create empty arrays or maps without spelling out a type:
use cbor_core::Value;
let empty_array = Value::array(());
let empty_map = Value::map(());
assert_eq!(empty_array.as_array().unwrap().len(), 0);
assert_eq!(empty_map.as_map().unwrap().len(), 0);Named constructors are available for cases where From is ambiguous:
| Constructor | Builds |
|---|---|
Value::null() | Null simple value |
Value::simple_value(v) | Arbitrary simple value |
Value::integer(v) | Integer (including big integers) |
Value::float(v) | Float in shortest CBOR form |
Value::array(v) | Array from slice, Vec, or fixed-size array |
Value::map(v) | Map from BTreeMap, HashMap, slice of pairs, etc. |
Value::tag(n, v) | Tagged value |
§Encoding and decoding
use cbor_core::Value;
let original = Value::from(-1000_i32);
let bytes = original.encode();
let decoded = Value::decode(&bytes).unwrap();
assert_eq!(original, decoded);For streaming use, write_to and
read_from operate on any io::Write / io::Read.
§Accessors
Accessor methods extract or borrow the inner data of each variant.
All return Result<T>, yielding Err(Error::IncompatibleType) on a
type mismatch. The naming follows Rust conventions:
| Prefix | Meaning | Returns |
|---|---|---|
as_* | Borrow inner data | &T or &mut T (with _mut) |
to_* | Convert or narrow | Owned Copy type (u8, f32, …) |
into_* | Consume self, extract | Owned T |
| no prefix | Trivial property | Copy scalar |
§Simple values
In CBOR, booleans and null are not distinct types but specific simple
values: false is 20, true is 21, null is 22. This means a
boolean value is always also a simple value. to_bool
provides typed access to true/false, while
to_simple_value works on any simple value
including booleans and null.
| Method | Returns | Notes |
|---|---|---|
to_simple_value | Result<u8> | Raw simple value number |
to_bool | Result<bool> | Only for true/false |
use cbor_core::Value;
let v = Value::from(true);
assert_eq!(v.to_bool().unwrap(), true);
assert_eq!(v.to_simple_value().unwrap(), 21); // CBOR true = simple(21)
// null is also a simple value
let n = Value::null();
assert!(n.to_bool().is_err()); // not a boolean
assert_eq!(n.to_simple_value().unwrap(), 22); // but is simple(22)§Integers
CBOR has two integer types (unsigned and negative) with different
internal representations. The to_* accessors perform checked
narrowing into any Rust integer type, returning Err(Overflow) if
the value does not fit, or Err(NegativeUnsigned) when extracting a
negative value into an unsigned type. Big integers (tags 2 and 3)
are handled transparently.
use cbor_core::Value;
let v = Value::from(1000_u32);
assert_eq!(v.to_u32().unwrap(), 1000);
assert_eq!(v.to_i64().unwrap(), 1000);
assert!(v.to_u8().is_err()); // overflow
let neg = Value::from(-5_i32);
assert_eq!(neg.to_i8().unwrap(), -5);
assert!(neg.to_u32().is_err()); // negative unsigned§Floats
Floats are stored internally in their shortest CBOR encoding (f16,
f32, or f64). to_f64 always succeeds since every
float can widen to f64. to_f32 fails with
Err(Precision) if the value is stored as f64.
use cbor_core::Value;
let v = Value::from(2.5_f32);
assert_eq!(v.to_f64().unwrap(), 2.5);
assert_eq!(v.to_f32().unwrap(), 2.5);§Byte strings
Byte strings are stored as Vec<u8>. Use as_bytes
for a borrowed slice, or into_bytes to take
ownership without copying.
| Method | Returns |
|---|---|
as_bytes | Result<&[u8]> |
as_bytes_mut | Result<&mut Vec<u8>> |
into_bytes | Result<Vec<u8>> |
use cbor_core::Value;
let mut v = Value::from(vec![1_u8, 2, 3]);
v.as_bytes_mut().unwrap().push(4);
assert_eq!(v.as_bytes().unwrap(), &[1, 2, 3, 4]);§Text strings
Text strings are stored as String (guaranteed valid UTF-8 by the
decoder). Use as_str for a borrowed &str, or
into_string to take ownership.
| Method | Returns |
|---|---|
as_str | Result<&str> |
as_string_mut | Result<&mut String> |
into_string | Result<String> |
use cbor_core::Value;
let v = Value::from("hello");
assert_eq!(v.as_str().unwrap(), "hello");
// Modify in place
let mut v = Value::from("hello");
v.as_string_mut().unwrap().push_str(" world");
assert_eq!(v.as_str().unwrap(), "hello world");§Arrays
Arrays are stored as Vec<Value>. Use as_array
to borrow the elements as a slice, or as_array_mut
to modify them in place.
| Method | Returns |
|---|---|
as_array | Result<&[Value]> |
as_array_mut | Result<&mut Vec<Value>> |
into_array | Result<Vec<Value>> |
use cbor_core::{Value, array};
let v = array![10, 20, 30];
let items = v.as_array().unwrap();
assert_eq!(items[1].to_u32().unwrap(), 20);
// Modify in place
let mut v = array![1, 2];
v.as_array_mut().unwrap().push(Value::from(3));
assert_eq!(v.as_array().unwrap().len(), 3);§Maps
Maps are stored as BTreeMap<Value, Value>, giving canonical key
order. Use standard BTreeMap methods on the result of
as_map to look up entries.
| Method | Returns |
|---|---|
as_map | Result<&BTreeMap<Value, Value>> |
as_map_mut | Result<&mut BTreeMap<Value, Value>> |
into_map | Result<BTreeMap<Value, Value>> |
use cbor_core::{Value, map};
let v = map! { "name" => "Alice", "age" => 30 };
let name = &v.as_map().unwrap()[&Value::from("name")];
assert_eq!(name.as_str().unwrap(), "Alice");
// Modify in place
let mut v = map! { "count" => 1 };
v.as_map_mut().unwrap().insert(Value::from("count"), Value::from(2));
assert_eq!(v.as_map().unwrap()[&Value::from("count")].to_u32().unwrap(), 2);§Tags
A tag wraps another value with a numeric label (e.g. tag 1 for epoch timestamps, tag 32 for URIs). Tags can be nested.
| Method | Returns | Notes |
|---|---|---|
tag_number | Result<u64> | Tag number |
tag_content | Result<&Value> | Borrowed content |
tag_content_mut | Result<&mut Value> | Mutable content |
as_tag | Result<(u64, &Value)> | Both parts |
as_tag_mut | Result<(u64, &mut Value)> | Mutable content |
into_tag | Result<(u64, Value)> | Consuming |
Use untagged to look through tags without removing
them, remove_tag to strip the outermost tag, or
remove_all_tags to strip all layers at once.
use cbor_core::Value;
// Create a tagged value (tag 32 = URI)
let mut uri = Value::tag(32, "https://example.com");
// Inspect
let (tag_num, content) = uri.as_tag().unwrap();
assert_eq!(tag_num, 32);
assert_eq!(content.as_str().unwrap(), "https://example.com");
// Look through tags without removing them
assert_eq!(uri.untagged().as_str().unwrap(), "https://example.com");
// Strip the tag in place
let removed = uri.remove_tag();
assert_eq!(removed, Some(32));
assert_eq!(uri.as_str().unwrap(), "https://example.com");Note that some CBOR types depend on their tag for interpretation.
Big integers, for example, are tagged byte strings (tags 2 and 3).
The integer accessors (to_u128, to_i128, etc.) recognise these
tags and decode the bytes automatically. If the tag is removed —
via remove_tag, remove_all_tags, or by consuming through
into_tag — the value becomes a plain byte string and can no
longer be read as an integer.
§Type introspection
data_type returns a DataType enum for
lightweight type checks without matching on the full enum.
use cbor_core::Value;
let v = Value::from(3.14_f64);
assert!(v.data_type().is_float());Variants§
SimpleValue(SimpleValue)
Simple value such as null, true, or false (major type 7).
In CBOR, booleans and null are simple values, not distinct types.
A Value::from(true) is stored as SimpleValue(21) and is
accessible through both to_bool and
to_simple_value.
Unsigned(u64)
Unsigned integer (major type 0). Stores values 0 through 2^64-1.
Negative(u64)
Negative integer (major type 1). The actual value is -1 - n, covering -1 through -2^64.
Float(Float)
IEEE 754 floating-point number (major type 7, additional info 25-27).
ByteString(Vec<u8>)
Byte string (major type 2).
TextString(String)
UTF-8 text string (major type 3).
Array(Vec<Value>)
Array of data items (major type 4).
Map(BTreeMap<Value, Value>)
Map of key-value pairs in canonical order (major type 5).
Tag(u64, Box<Value>)
Tagged data item (major type 6). The first field is the tag number, the second is the enclosed content.
Implementations§
Source§impl Value
impl Value
Sourcepub fn encode(&self) -> Vec<u8> ⓘ
pub fn encode(&self) -> Vec<u8> ⓘ
Encode this value to CBOR bytes.
use cbor_core::Value;
let bytes = Value::from(42_u32).encode();
assert_eq!(bytes, [0x18, 42]);Sourcepub fn decode(bytes: &[u8]) -> Result<Self>
pub fn decode(bytes: &[u8]) -> Result<Self>
Decode a CBOR data item from a byte slice.
Returns Err if the encoding is not canonical.
use cbor_core::Value;
let v = Value::decode(&[0x18, 42]).unwrap();
assert_eq!(v.to_u32().unwrap(), 42);Sourcepub fn read_from(reader: &mut impl Read) -> Result<Self>
pub fn read_from(reader: &mut impl Read) -> Result<Self>
Read a single CBOR data item from a stream.
Sourcepub fn write_to(&self, writer: &mut impl Write) -> Result<()>
pub fn write_to(&self, writer: &mut impl Write) -> Result<()>
Write this value as CBOR to a stream.
Sourcepub fn simple_value(value: impl TryInto<SimpleValue>) -> Self
pub fn simple_value(value: impl TryInto<SimpleValue>) -> Self
Create a CBOR simple value.
§Panics
Panics if the value is in the reserved range 24-31.
Use SimpleValue::from_u8 for a fallible alternative.
Sourcepub fn integer(value: impl Into<Integer>) -> Self
pub fn integer(value: impl Into<Integer>) -> Self
Create a CBOR integer. Accepts any Rust integer type. Values beyond the u64/i64 range are encoded as big integers (tags 2/3).
Sourcepub fn float(value: impl Into<Float>) -> Self
pub fn float(value: impl Into<Float>) -> Self
Create a CBOR float. The value is stored in the shortest IEEE 754 form (f16, f32, or f64) that preserves it exactly.
Sourcepub fn array(array: impl Into<Array>) -> Self
pub fn array(array: impl Into<Array>) -> Self
Create a CBOR array from a Vec, slice, or fixed-size array.
Sourcepub fn tag(number: u64, content: impl Into<Value>) -> Self
pub fn tag(number: u64, content: impl Into<Value>) -> Self
Wrap a value with a CBOR tag.
use cbor_core::Value;
let uri = Value::tag(32, "https://example.com");
assert_eq!(uri.tag_number().unwrap(), 32);Sourcepub const fn data_type(&self) -> DataType
pub const fn data_type(&self) -> DataType
Return the DataType of this value for type-level dispatch.
Sourcepub const fn to_bool(&self) -> Result<bool>
pub const fn to_bool(&self) -> Result<bool>
Extract a boolean. Returns Err for non-boolean values.
Sourcepub const fn to_simple_value(&self) -> Result<u8>
pub const fn to_simple_value(&self) -> Result<u8>
Extract the raw simple value number (0-255, excluding 24-31).
Sourcepub const fn to_u8(&self) -> Result<u8>
pub const fn to_u8(&self) -> Result<u8>
Narrow to u8. Returns Err(Overflow) or Err(NegativeUnsigned) on mismatch.
Sourcepub fn to_u128(&self) -> Result<u128>
pub fn to_u128(&self) -> Result<u128>
Narrow to u128. Handles big integers (tag 2) transparently.
Sourcepub fn to_i128(&self) -> Result<i128>
pub fn to_i128(&self) -> Result<i128>
Narrow to i128. Handles big integers (tags 2 and 3) transparently.
Sourcepub fn to_f32(&self) -> Result<f32>
pub fn to_f32(&self) -> Result<f32>
Convert to f32. Returns Err(Precision) for f64-width values.
Sourcepub const fn as_bytes_mut(&mut self) -> Result<&mut Vec<u8>>
pub const fn as_bytes_mut(&mut self) -> Result<&mut Vec<u8>>
Borrow the byte string as a mutable Vec.
Sourcepub fn into_bytes(self) -> Result<Vec<u8>>
pub fn into_bytes(self) -> Result<Vec<u8>>
Take ownership of the byte string.
Sourcepub const fn as_string_mut(&mut self) -> Result<&mut String>
pub const fn as_string_mut(&mut self) -> Result<&mut String>
Borrow the text string as a mutable String.
Sourcepub fn into_string(self) -> Result<String>
pub fn into_string(self) -> Result<String>
Take ownership of the text string.
Sourcepub const fn as_array_mut(&mut self) -> Result<&mut Vec<Value>>
pub const fn as_array_mut(&mut self) -> Result<&mut Vec<Value>>
Borrow the array as a mutable Vec.
Sourcepub fn into_array(self) -> Result<Vec<Value>>
pub fn into_array(self) -> Result<Vec<Value>>
Take ownership of the array.
Sourcepub const fn as_map_mut(&mut self) -> Result<&mut BTreeMap<Value, Value>>
pub const fn as_map_mut(&mut self) -> Result<&mut BTreeMap<Value, Value>>
Borrow the map mutably.
Sourcepub const fn tag_number(&self) -> Result<u64>
pub const fn tag_number(&self) -> Result<u64>
Return the tag number.
Sourcepub const fn tag_content(&self) -> Result<&Self>
pub const fn tag_content(&self) -> Result<&Self>
Borrow the tag content.
Sourcepub const fn tag_content_mut(&mut self) -> Result<&mut Self>
pub const fn tag_content_mut(&mut self) -> Result<&mut Self>
Mutably borrow the tag content.
Sourcepub fn as_tag_mut(&mut self) -> Result<(u64, &mut Value)>
pub fn as_tag_mut(&mut self) -> Result<(u64, &mut Value)>
Borrow tag number and mutable content together.
Sourcepub fn remove_tag(&mut self) -> Option<u64>
pub fn remove_tag(&mut self) -> Option<u64>
Remove the outermost tag, returning its number. Returns None if
the value is not tagged.
Remove all nested tags, returning their numbers from outermost to innermost.
Sourcepub const fn untagged(&self) -> &Self
pub const fn untagged(&self) -> &Self
Borrow the innermost non-tag value, skipping all tag wrappers.
Sourcepub const fn untagged_mut(&mut self) -> &mut Self
pub const fn untagged_mut(&mut self) -> &mut Self
Mutable version of untagged.
Sourcepub fn into_untagged(self) -> Self
pub fn into_untagged(self) -> Self
Consuming version of untagged.