Skip to main content

deser_core/
extensions.rs

1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::any::{Any, TypeId, type_name};
4use core::fmt::{self, Debug};
5
6#[derive(Copy, Clone)]
7pub(crate) struct TypeKey(TypeId, &'static str);
8
9impl TypeKey {
10    pub(crate) fn of<T: 'static>() -> TypeKey {
11        TypeKey(TypeId::of::<T>(), type_name::<T>())
12    }
13}
14
15impl PartialEq for TypeKey {
16    fn eq(&self, other: &Self) -> bool {
17        self.0 == other.0
18    }
19}
20
21impl Eq for TypeKey {}
22
23impl Debug for TypeKey {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        write!(f, "{}", self.1)
26    }
27}
28
29trait DebugAny: Any + Debug + Send + Sync {
30    fn as_any(&self) -> &dyn Any;
31    fn as_any_mut(&mut self) -> &mut dyn Any;
32    fn into_any(self: Box<Self>) -> Box<dyn Any>;
33}
34
35impl<T: Any + Debug + Send + Sync + 'static> DebugAny for T {
36    fn as_any(&self) -> &dyn Any {
37        self
38    }
39
40    fn as_any_mut(&mut self) -> &mut dyn Any {
41        self
42    }
43
44    fn into_any(self: Box<Self>) -> Box<dyn Any> {
45        self
46    }
47}
48
49/// The values of event data are also `Sync` so that captured event data
50/// can be shared between threads (see [`EventData`]).
51trait EventAny: DebugAny + Sync {}
52
53impl<T: DebugAny + Sync> EventAny for T {}
54
55/// Functions to clone values of a type behind a `dyn DebugAny`.
56#[derive(Copy, Clone)]
57struct CloneFns {
58    clone: fn(&dyn DebugAny) -> Box<dyn DebugAny>,
59    clone_into: fn(&mut dyn DebugAny, &dyn DebugAny),
60}
61
62impl CloneFns {
63    fn of<T: Clone + Debug + Send + Sync + 'static>() -> CloneFns {
64        CloneFns {
65            clone: |value| Box::new(value.as_any().downcast_ref::<T>().unwrap().clone()),
66            clone_into: |target, value| {
67                target
68                    .as_any_mut()
69                    .downcast_mut::<T>()
70                    .unwrap()
71                    .clone_from(value.as_any().downcast_ref::<T>().unwrap())
72            },
73        }
74    }
75}
76
77/// Functions to clone event data behind a `dyn EventAny`.
78#[derive(Copy, Clone)]
79struct EventFns {
80    clone: fn(&dyn EventAny) -> Box<dyn EventAny>,
81    clone_into: fn(&mut dyn EventAny, &dyn EventAny),
82}
83
84impl EventFns {
85    fn of<T: Clone + Debug + Send + Sync + 'static>() -> EventFns {
86        EventFns {
87            clone: |value| Box::new(value.as_any().downcast_ref::<T>().unwrap().clone()),
88            clone_into: |target, value| {
89                target
90                    .as_any_mut()
91                    .downcast_mut::<T>()
92                    .unwrap()
93                    .clone_from(value.as_any().downcast_ref::<T>().unwrap())
94            },
95        }
96    }
97}
98
99/// A value attached to the current event.
100struct EventEntry {
101    key: TypeKey,
102    // values are retained when they are deactivated so that their memory
103    // can be reused for the next event.
104    active: bool,
105    value: Box<dyn EventAny>,
106    fns: EventFns,
107}
108
109/// Typed values stored in a state.
110///
111/// There are typically only a handful of extension types in a state which
112/// is why they are held in a vector and looked up linearly.  This is much
113/// faster than a hash map for small numbers of entries.
114#[derive(Default)]
115pub(crate) struct Extensions {
116    // Invariant: the value of an entry is always of the type of its key.
117    entries: Vec<(TypeKey, Box<dyn DebugAny>)>,
118    replayable: Vec<(TypeKey, CloneFns)>,
119    // Invariant: the value of an entry is always of the type of its key.
120    events: Vec<EventEntry>,
121    // `true` if any of the event entries is active
122    has_event_data: bool,
123}
124
125impl Debug for Extensions {
126    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127        f.debug_map()
128            .entries(self.entries.iter().map(|(key, value)| (key, value)))
129            .entries(
130                self.events
131                    .iter()
132                    .filter(|entry| entry.active)
133                    .map(|entry| (entry.key, &entry.value)),
134            )
135            .finish()
136    }
137}
138
139impl Extensions {
140    #[inline]
141    fn position(&self, key: TypeId) -> Option<usize> {
142        self.entries.iter().position(|(k, _)| k.0 == key)
143    }
144
145    #[inline]
146    pub(crate) fn get<T: Debug + Send + Sync + 'static>(&self) -> Option<&T> {
147        let index = self.position(TypeId::of::<T>())?;
148        let value: &dyn DebugAny = &*self.entries[index].1;
149        // SAFETY: values are always stored with the key of their type
150        Some(unsafe { &*(value as *const dyn DebugAny).cast::<T>() })
151    }
152
153    #[inline]
154    pub(crate) fn get_mut<T: Default + Debug + Send + Sync + 'static>(&mut self) -> &mut T {
155        let index = match self.position(TypeId::of::<T>()) {
156            Some(index) => index,
157            None => self.insert_default::<T>(),
158        };
159        let value: &mut dyn DebugAny = &mut *self.entries[index].1;
160        // SAFETY: values are always stored with the key of their type
161        unsafe { &mut *(value as *mut dyn DebugAny).cast::<T>() }
162    }
163
164    #[cold]
165    fn insert_default<T: Default + Debug + Send + Sync + 'static>(&mut self) -> usize {
166        self.entries
167            .push((TypeKey::of::<T>(), Box::new(T::default())));
168        self.entries.len() - 1
169    }
170
171    /// Marks an extension type as replayable.
172    pub(crate) fn set_replayable<T: Clone + Debug + Send + Sync + 'static>(&mut self) {
173        let key = TypeKey::of::<T>();
174        if !self.replayable.iter().any(|(k, _)| *k == key) {
175            self.replayable.push((key, CloneFns::of::<T>()));
176        }
177    }
178
179    /// Returns `true` if data is attached to the current event.
180    #[cfg(test)]
181    pub fn has_event_data(&self) -> bool {
182        self.has_event_data
183    }
184
185    #[inline]
186    fn event_position(&self, key: TypeId) -> Option<usize> {
187        self.events.iter().position(|entry| entry.key.0 == key)
188    }
189
190    /// Returns the data of a type attached to the current event.
191    ///
192    /// Most events have no data.  The check for that is always inlined, so
193    /// that looking up event data is cheap for them.
194    #[inline(always)]
195    pub(crate) fn event<T: Debug + Send + Sync + 'static>(&self) -> Option<&T> {
196        if !self.has_event_data {
197            return None;
198        }
199        self.find_event()
200    }
201
202    #[inline]
203    fn find_event<T: Debug + Send + Sync + 'static>(&self) -> Option<&T> {
204        let entry = &self.events[self.event_position(TypeId::of::<T>())?];
205        if !entry.active {
206            return None;
207        }
208        // SAFETY: values are always stored with the key of their type
209        Some(unsafe { &*(&*entry.value as *const dyn EventAny).cast::<T>() })
210    }
211
212    /// Returns the data of a type attached to the current event mutably.
213    ///
214    /// If no such data is attached yet, the default value is attached.
215    #[inline]
216    pub(crate) fn event_mut<T: Default + Clone + Debug + Send + Sync + 'static>(
217        &mut self,
218    ) -> &mut T {
219        let index = match self.event_position(TypeId::of::<T>()) {
220            Some(index) => index,
221            None => self.insert_event::<T>(),
222        };
223        let entry = &mut self.events[index];
224        // SAFETY: values are always stored with the key of their type
225        let value = unsafe { &mut *(&mut *entry.value as *mut dyn EventAny).cast::<T>() };
226        if !entry.active {
227            // the value of a previous event is reset in place which retains
228            // the memory of collections
229            value.clone_from(&T::default());
230            entry.active = true;
231            self.has_event_data = true;
232        }
233        value
234    }
235
236    /// Takes the data of a type from the current event.
237    ///
238    /// The data is detached from the event.
239    pub(crate) fn take_event<T: Default + Debug + Send + Sync + 'static>(&mut self) -> Option<T> {
240        if !self.has_event_data {
241            return None;
242        }
243        let index = self.event_position(TypeId::of::<T>())?;
244        let entry = &mut self.events[index];
245        if !entry.active {
246            return None;
247        }
248        // `as_any_mut` of the box itself would be the box
249        let value = core::mem::take((*entry.value).as_any_mut().downcast_mut::<T>()?);
250        entry.active = false;
251        self.has_event_data = self.events.iter().any(|entry| entry.active);
252        Some(value)
253    }
254
255    #[cold]
256    fn insert_event<T: Default + Clone + Debug + Send + Sync + 'static>(&mut self) -> usize {
257        self.events.push(EventEntry {
258            key: TypeKey::of::<T>(),
259            active: false,
260            value: Box::new(T::default()),
261            fns: EventFns::of::<T>(),
262        });
263        self.events.len() - 1
264    }
265
266    /// Detaches all data from the current event.
267    #[inline(always)]
268    pub(crate) fn clear_event_data(&mut self) {
269        if self.has_event_data {
270            self.deactivate_events();
271        }
272    }
273
274    #[inline(never)]
275    fn deactivate_events(&mut self) {
276        for entry in self.events.iter_mut() {
277            entry.active = false;
278        }
279        self.has_event_data = false;
280    }
281
282    /// Captures the values of the replayable extensions and the event data.
283    ///
284    /// Returns `None` if there is nothing to capture.  Most of the time
285    /// there is neither, this is cheap to check.
286    #[inline]
287    pub(crate) fn snapshot_if_any(&self) -> Option<Snapshot> {
288        if self.replayable.is_empty() && !self.has_event_data {
289            return None;
290        }
291        Some(self.snapshot()).filter(|snapshot| !snapshot.is_empty())
292    }
293
294    /// Captures the values of the replayable extensions and the event data.
295    pub(crate) fn snapshot(&self) -> Snapshot {
296        let mut snapshot = Snapshot::default();
297        if !self.replayable.is_empty() {
298            snapshot.replayable = self
299                .replayable
300                .iter()
301                .filter_map(|&(key, fns)| {
302                    self.position(key.0)
303                        .map(|index| (key, (fns.clone)(&*self.entries[index].1), fns))
304                })
305                .collect();
306        }
307        snapshot.events = self.capture_event_data();
308        snapshot
309    }
310
311    /// Restores the values from a snapshot.
312    ///
313    /// The event data is replaced by the event data of the snapshot.
314    pub(crate) fn restore(&mut self, snapshot: &Snapshot) {
315        // the clone functions belong to the type of the key
316        for (key, value, fns) in snapshot.replayable.iter() {
317            match self.position(key.0) {
318                Some(index) => (fns.clone_into)(&mut *self.entries[index].1, &**value),
319                None => self.entries.push((*key, (fns.clone)(&**value))),
320            }
321        }
322        self.restore_event_data(&snapshot.events);
323    }
324
325    /// Captures the data attached to the current event.
326    pub(crate) fn capture_event_data(&self) -> EventData {
327        if !self.has_event_data {
328            return EventData::default();
329        }
330        EventData {
331            entries: self
332                .events
333                .iter()
334                .filter(|entry| entry.active)
335                .map(|entry| EventDataEntry {
336                    key: entry.key,
337                    value: (entry.fns.clone)(&*entry.value),
338                    fns: entry.fns,
339                })
340                .collect(),
341        }
342    }
343
344    /// Replaces the data attached to the current event.
345    pub(crate) fn restore_event_data(&mut self, data: &EventData) {
346        self.clear_event_data();
347        self.attach_event_data(data);
348    }
349
350    /// Attaches data to the current event.
351    ///
352    /// Data of the same types that is already attached is replaced, other
353    /// data is retained.
354    pub(crate) fn attach_event_data(&mut self, data: &EventData) {
355        for entry in data.entries.iter() {
356            match self.event_position(entry.key.0) {
357                Some(index) => {
358                    let target = &mut self.events[index];
359                    (entry.fns.clone_into)(&mut *target.value, &*entry.value);
360                    target.active = true;
361                }
362                None => self.events.push(EventEntry {
363                    key: entry.key,
364                    active: true,
365                    value: (entry.fns.clone)(&*entry.value),
366                    fns: entry.fns,
367                }),
368            }
369            self.has_event_data = true;
370        }
371    }
372}
373
374/// The captured values of the replayable extensions and the event data.
375#[derive(Default)]
376pub(crate) struct Snapshot {
377    replayable: Vec<(TypeKey, Box<dyn DebugAny>, CloneFns)>,
378    events: EventData,
379}
380
381impl Snapshot {
382    /// Returns `true` if nothing was captured.
383    pub(crate) fn is_empty(&self) -> bool {
384        self.replayable.is_empty() && self.events.is_empty()
385    }
386
387    /// Returns the captured event data.
388    pub(crate) fn event_data(&self) -> &EventData {
389        &self.events
390    }
391}
392
393impl Clone for Snapshot {
394    fn clone(&self) -> Snapshot {
395        Snapshot {
396            replayable: self
397                .replayable
398                .iter()
399                .map(|(key, value, fns)| (*key, (fns.clone)(&**value), *fns))
400                .collect(),
401            events: self.events.clone(),
402        }
403    }
404}
405
406impl Debug for Snapshot {
407    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
408        f.debug_map()
409            .entries(self.replayable.iter().map(|(key, value, _)| (key, value)))
410            .entries(
411                self.events
412                    .entries
413                    .iter()
414                    .map(|entry| (entry.key, &entry.value)),
415            )
416            .finish()
417    }
418}
419
420/// Data attached to an event, detached from the event.
421///
422/// Formats and values attach data to individual events (see
423/// [`State::event`](crate::State::event)), for instance tags or formatting
424/// hints.  This captures such data so that it can be attached to an event
425/// again later.  This is used by types which hold on to values outside of a
426/// serialization or deserialization, such as the values of the
427/// `deser-value` crate, so that data like CBOR tags survives.
428///
429/// ```
430/// use deser::de::DeserializeDriver;
431/// use deser::EventData;
432///
433/// #[derive(Debug, Default, Clone, PartialEq)]
434/// struct Tag(u64);
435///
436/// let mut data = EventData::new();
437/// data.insert(Tag(42));
438/// assert_eq!(data.get::<Tag>(), Some(&Tag(42)));
439///
440/// let mut out = None::<bool>;
441/// let mut driver = DeserializeDriver::new(&mut out);
442/// driver.state_mut().attach_event_data(&data);
443/// assert_eq!(driver.state().event::<Tag>(), Some(&Tag(42)));
444/// assert_eq!(
445///     driver.state().capture_event_data().get::<Tag>(),
446///     Some(&Tag(42))
447/// );
448/// ```
449///
450/// Event data has to be [`Send`] and [`Sync`], which means that captured
451/// event data is too.
452#[derive(Default)]
453pub struct EventData {
454    // Invariant: the value of an entry is always of the type of its key and
455    // there is at most one entry per key.
456    entries: Vec<EventDataEntry>,
457}
458
459struct EventDataEntry {
460    key: TypeKey,
461    value: Box<dyn EventAny>,
462    fns: EventFns,
463}
464
465impl EventData {
466    /// Creates empty event data.
467    pub const fn new() -> EventData {
468        EventData {
469            entries: Vec::new(),
470        }
471    }
472
473    /// Returns `true` if no data is held.
474    pub fn is_empty(&self) -> bool {
475        self.entries.is_empty()
476    }
477
478    fn position(&self, key: TypeId) -> Option<usize> {
479        self.entries.iter().position(|entry| entry.key.0 == key)
480    }
481
482    /// Returns the data of a type.
483    pub fn get<T: Debug + Send + 'static>(&self) -> Option<&T> {
484        let entry = &self.entries[self.position(TypeId::of::<T>())?];
485        // SAFETY: values are always stored with the key of their type
486        Some(unsafe { &*(&*entry.value as *const dyn EventAny).cast::<T>() })
487    }
488
489    /// Returns the data of a type mutably.
490    ///
491    /// If there is no data of this type, the default value is inserted.
492    pub fn get_mut<T: Default + Clone + Debug + Send + Sync + 'static>(&mut self) -> &mut T {
493        let index = match self.position(TypeId::of::<T>()) {
494            Some(index) => index,
495            None => {
496                self.entries.push(EventDataEntry {
497                    key: TypeKey::of::<T>(),
498                    value: Box::new(T::default()),
499                    fns: EventFns::of::<T>(),
500                });
501                self.entries.len() - 1
502            }
503        };
504        let entry = &mut self.entries[index];
505        // SAFETY: values are always stored with the key of their type
506        unsafe { &mut *(&mut *entry.value as *mut dyn EventAny).cast::<T>() }
507    }
508
509    /// Inserts data, replacing data of the same type.
510    pub fn insert<T: Clone + Debug + Send + Sync + 'static>(&mut self, value: T) {
511        let entry = EventDataEntry {
512            key: TypeKey::of::<T>(),
513            value: Box::new(value),
514            fns: EventFns::of::<T>(),
515        };
516        match self.position(TypeId::of::<T>()) {
517            Some(index) => self.entries[index] = entry,
518            None => self.entries.push(entry),
519        }
520    }
521
522    /// Removes the data of a type and returns it.
523    pub fn remove<T: Debug + Send + 'static>(&mut self) -> Option<T> {
524        let entry = self.entries.remove(self.position(TypeId::of::<T>())?);
525        entry
526            .value
527            .into_any()
528            .downcast::<T>()
529            .ok()
530            .map(|value| *value)
531    }
532}
533
534impl Clone for EventData {
535    fn clone(&self) -> EventData {
536        EventData {
537            entries: self
538                .entries
539                .iter()
540                .map(|entry| EventDataEntry {
541                    key: entry.key,
542                    value: (entry.fns.clone)(&*entry.value),
543                    fns: entry.fns,
544                })
545                .collect(),
546        }
547    }
548}
549
550impl Debug for EventData {
551    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
552        f.debug_map()
553            .entries(self.entries.iter().map(|entry| (entry.key, &entry.value)))
554            .finish()
555    }
556}
557
558#[test]
559fn test_extensions() {
560    #[derive(Debug, Default, Clone, PartialEq)]
561    struct A(u32);
562    #[derive(Debug, Default, Clone, PartialEq)]
563    struct B(String);
564    #[derive(Debug, Default, Clone, PartialEq)]
565    struct C(u8);
566
567    let mut ext = Extensions::default();
568    assert_eq!(ext.get::<A>(), None);
569    ext.get_mut::<A>().0 = 42;
570    ext.get_mut::<B>().0.push_str("hello");
571    ext.get_mut::<C>().0 = 1;
572    assert_eq!(ext.get::<A>(), Some(&A(42)));
573    assert_eq!(ext.get::<B>(), Some(&B("hello".into())));
574    assert_eq!(ext.get::<C>(), Some(&C(1)));
575
576    ext.set_replayable::<A>();
577    ext.set_replayable::<B>();
578    ext.set_replayable::<A>();
579    let snapshot = ext.snapshot();
580    ext.get_mut::<A>().0 = 1;
581    ext.get_mut::<B>().0.clear();
582    ext.get_mut::<C>().0 = 2;
583    ext.restore(&snapshot);
584    assert_eq!(ext.get::<A>(), Some(&A(42)));
585    assert_eq!(ext.get::<B>(), Some(&B("hello".into())));
586    assert_eq!(ext.get::<C>(), Some(&C(2)));
587
588    // restoring into empty extensions inserts the values
589    let mut other = Extensions::default();
590    other.restore(&snapshot.clone());
591    assert_eq!(other.get::<A>(), Some(&A(42)));
592    assert_eq!(other.get::<C>(), None);
593    assert_eq!(
594        format!("{:?}", other),
595        format!(
596            "{{{}: A(42), {}: B(\"hello\")}}",
597            core::any::type_name::<A>(),
598            core::any::type_name::<B>()
599        )
600    );
601}
602
603#[test]
604fn test_event_data() {
605    #[derive(Debug, Default, PartialEq)]
606    struct Tags(Vec<u64>);
607
608    // derived clones do not forward `clone_from`
609    impl Clone for Tags {
610        fn clone(&self) -> Tags {
611            Tags(self.0.clone())
612        }
613
614        fn clone_from(&mut self, source: &Tags) {
615            self.0.clone_from(&source.0);
616        }
617    }
618    #[derive(Debug, Default, Clone, PartialEq)]
619    struct Span(usize, usize);
620
621    let mut ext = Extensions::default();
622    assert!(!ext.has_event_data());
623    assert_eq!(ext.event::<Tags>(), None);
624
625    ext.event_mut::<Tags>().0.extend([1, 2]);
626    assert!(ext.has_event_data());
627    assert_eq!(ext.event::<Tags>(), Some(&Tags(vec![1, 2])));
628    assert_eq!(ext.event::<Span>(), None);
629
630    // clearing detaches the data but retains the memory
631    ext.clear_event_data();
632    assert!(!ext.has_event_data());
633    assert_eq!(ext.event::<Tags>(), None);
634    let tags = ext.event_mut::<Tags>();
635    assert_eq!(tags, &Tags(vec![]));
636    assert!(tags.0.capacity() >= 2);
637    tags.0.push(3);
638    *ext.event_mut::<Span>() = Span(1, 2);
639
640    // snapshots capture only the attached data
641    let snapshot = ext.snapshot();
642    ext.clear_event_data();
643    *ext.event_mut::<Span>() = Span(3, 4);
644    ext.restore(&snapshot);
645    assert_eq!(ext.event::<Tags>(), Some(&Tags(vec![3])));
646    assert_eq!(ext.event::<Span>(), Some(&Span(1, 2)));
647
648    ext.clear_event_data();
649    ext.event_mut::<Span>();
650    let empty = ext.snapshot();
651    *ext.event_mut::<Tags>() = Tags(vec![4]);
652    ext.restore(&empty);
653    assert_eq!(ext.event::<Tags>(), None);
654    assert_eq!(ext.event::<Span>(), Some(&Span(0, 0)));
655
656    // taking detaches the data of one type, it's not captured anymore
657    *ext.event_mut::<Tags>() = Tags(vec![5]);
658    assert_eq!(ext.take_event::<Tags>(), Some(Tags(vec![5])));
659    assert_eq!(ext.take_event::<Tags>(), None);
660    assert_eq!(ext.event::<Tags>(), None);
661    assert_eq!(ext.event::<Span>(), Some(&Span(0, 0)));
662    assert!(ext.capture_event_data().entries.len() == 1);
663    assert_eq!(ext.take_event::<Span>(), Some(Span(0, 0)));
664    assert!(!ext.has_event_data());
665    assert!(ext.capture_event_data().is_empty());
666}