pub struct TlsMap<K, V> { /* private fields */ }Expand description
A sorted key-value map with deterministic TLS codec serialization.
Entries are maintained in sorted order by key, ensuring byte-identical serialization across all implementations. Keys must be unique.
Wire format: vlen(total_byte_length) || entry[0] || entry[1] || ...
where each entry is K(tls) || V(tls) and vlen is the QUIC
variable-length encoding (RFC 9000 §16).
§Examples
use xmtp_mls_common::tls_map::TlsMap;
use tls_codec::{Serialize, Deserialize};
let mut map = TlsMap::<u16, u16>::new();
map.insert(3, 30).unwrap();
map.insert(1, 10).unwrap();
map.insert(2, 20).unwrap();
// Serialization is deterministic regardless of insertion order
let bytes = map.tls_serialize_detached().unwrap();
let deserialized = TlsMap::<u16, u16>::tls_deserialize_exact(&bytes).unwrap();
assert_eq!(map, deserialized);Implementations§
Source§impl<K, V> TlsMap<K, V>
impl<K, V> TlsMap<K, V>
Sourcepub fn new() -> Self
pub fn new() -> Self
Create an empty map.
use xmtp_mls_common::tls_map::TlsMap;
let map = TlsMap::<u8, u16>::new();
assert!(map.is_empty());Sourcepub fn from_pairs(iter: impl IntoIterator<Item = (K, V)>) -> Self
pub fn from_pairs(iter: impl IntoIterator<Item = (K, V)>) -> Self
Create a map from an iterator of key-value pairs.
Entries are sorted by key. If duplicate keys exist, the last value wins.
use xmtp_mls_common::tls_map::TlsMap;
let map = TlsMap::from_pairs([(2, "b"), (1, "a"), (2, "c")]);
assert_eq!(map.get(&1), Some(&"a"));
assert_eq!(map.get(&2), Some(&"c")); // last value wins
assert_eq!(map.len(), 2);Sourcepub fn insert(&mut self, key: K, value: V) -> Result<(), TlsMapError>
pub fn insert(&mut self, key: K, value: V) -> Result<(), TlsMapError>
Insert a key-value pair. Returns an error if the key already exists.
use xmtp_mls_common::tls_map::TlsMap;
let mut map = TlsMap::<u8, u8>::new();
assert!(map.insert(1, 10).is_ok());
assert!(map.insert(1, 20).is_err()); // duplicate keySourcepub fn update(&mut self, key: K, value: V) -> Result<(), TlsMapError>
pub fn update(&mut self, key: K, value: V) -> Result<(), TlsMapError>
Update an existing key’s value. Returns an error if the key doesn’t exist.
use xmtp_mls_common::tls_map::TlsMap;
let mut map = TlsMap::<u8, u8>::new();
map.insert(1, 10).unwrap();
map.update(1, 20).unwrap();
assert_eq!(map.get(&1), Some(&20));
assert!(map.update(99, 0).is_err()); // key not foundSourcepub fn set(&mut self, key: K, value: V)
pub fn set(&mut self, key: K, value: V)
Insert or update a key-value pair. Always succeeds.
use xmtp_mls_common::tls_map::TlsMap;
let mut map = TlsMap::<u8, u8>::new();
map.set(1, 10);
map.set(1, 20); // overwrites
assert_eq!(map.get(&1), Some(&20));
assert_eq!(map.len(), 1);Sourcepub fn remove(&mut self, key: &K) -> Result<V, TlsMapError>
pub fn remove(&mut self, key: &K) -> Result<V, TlsMapError>
Remove a key. Returns the removed value, or an error if the key doesn’t exist.
use xmtp_mls_common::tls_map::TlsMap;
let mut map = TlsMap::<u8, u8>::new();
map.insert(1, 10).unwrap();
assert_eq!(map.remove(&1).unwrap(), 10);
assert!(map.remove(&1).is_err()); // already removedSourcepub fn get(&self, key: &K) -> Option<&V>
pub fn get(&self, key: &K) -> Option<&V>
Get a value by key. Returns None if the key is not present.
use xmtp_mls_common::tls_map::TlsMap;
let mut map = TlsMap::<u8, u8>::new();
map.insert(1, 10).unwrap();
assert_eq!(map.get(&1), Some(&10));
assert_eq!(map.get(&2), None);Sourcepub fn get_mut(&mut self, key: &K) -> Option<&mut V>
pub fn get_mut(&mut self, key: &K) -> Option<&mut V>
Get a mutable reference to a value by key. Returns None if the key is not present.
use xmtp_mls_common::tls_map::TlsMap;
let mut map = TlsMap::<u8, u8>::new();
map.insert(1, 10).unwrap();
*map.get_mut(&1).unwrap() = 20;
assert_eq!(map.get(&1), Some(&20));Sourcepub fn contains_key(&self, key: &K) -> bool
pub fn contains_key(&self, key: &K) -> bool
Check if a key exists in the map.
Source§impl<K, V> TlsMap<K, V>
impl<K, V> TlsMap<K, V>
Sourcepub fn apply_delta(
&mut self,
delta: TlsMapDelta<K, V>,
) -> Result<(), TlsMapError>
pub fn apply_delta( &mut self, delta: TlsMapDelta<K, V>, ) -> Result<(), TlsMapError>
Apply a delta atomically. If any mutation fails, the map is unchanged.
use xmtp_mls_common::tls_map::{TlsMap, TlsMapDelta};
let mut map = TlsMap::<u8, u8>::new();
map.insert(1, 10).unwrap();
let delta = TlsMapDelta::new()
.insert(2, 20)
.update(1, 15)
.delete(1);
map.apply_delta(delta).unwrap();
assert_eq!(map.get(&2), Some(&20));
assert!(!map.contains_key(&1));Trait Implementations§
Source§impl<K, V> Deserialize for TlsMap<K, V>
impl<K, V> Deserialize for TlsMap<K, V>
Source§fn tls_deserialize<R: Read>(bytes: &mut R) -> Result<Self, Error>where
Self: Sized,
fn tls_deserialize<R: Read>(bytes: &mut R) -> Result<Self, Error>where
Self: Sized,
bytes from the provided a std::io::Read
and returns the populated struct. Read moreSource§impl<K, V> IntoIterator for TlsMap<K, V>
impl<K, V> IntoIterator for TlsMap<K, V>
Source§impl<K: PartialEq, V: PartialEq> PartialEq for TlsMap<K, V>
impl<K: PartialEq, V: PartialEq> PartialEq for TlsMap<K, V>
impl<K: Eq, V: Eq> Eq for TlsMap<K, V>
impl<K, V> StructuralPartialEq for TlsMap<K, V>
Auto Trait Implementations§
impl<K, V> Freeze for TlsMap<K, V>
impl<K, V> RefUnwindSafe for TlsMap<K, V>where
K: RefUnwindSafe,
V: RefUnwindSafe,
impl<K, V> Send for TlsMap<K, V>
impl<K, V> Sync for TlsMap<K, V>
impl<K, V> Unpin for TlsMap<K, V>
impl<K, V> UnsafeUnpin for TlsMap<K, V>
impl<K, V> UnwindSafe for TlsMap<K, V>where
K: UnwindSafe,
V: UnwindSafe,
Blanket Implementations§
§impl<T> AggregateExpressionMethods for T
impl<T> AggregateExpressionMethods for T
§fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
DISTINCT modifier for aggregate functions Read more§fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
ALL modifier for aggregate functions Read more§fn aggregate_filter<P>(self, f: P) -> Self::Outputwhere
P: AsExpression<Bool>,
Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,
fn aggregate_filter<P>(self, f: P) -> Self::Outputwhere
P: AsExpression<Bool>,
Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,
§fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<T> IntoSql for T
impl<T> IntoSql for T
§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].