Skip to main content

ferroui_reactiveui/reactive_object/
reactive_record.rs

1//! `ReactiveRecord` (`ReactiveUI.Shared/ReactiveObject/ReactiveRecord.cs`).
2
3use crate::ReactiveObject;
4use std::fmt;
5use std::hash::{Hash, Hasher};
6use std::ops::Deref;
7
8/// The part of a reactive record (`ReactiveRecord`): a [`ReactiveObject`] for a type with value
9/// equality. The notification state is not data: two parts are always equal, hash to nothing and
10/// print nothing, so a record that derives `PartialEq`, `Eq`, `Hash` and `Debug` compares, hashes
11/// and prints its own members only, as upstream's record does.
12///
13/// Deviation (DEVIATIONS.md, ReactiveUI): a clone of the part is a new part without handlers or
14/// state, the counterpart of the copy of a record (`with`), which gets its own state upstream.
15///
16/// ```
17/// use ferroui_reactiveui::{reactive_object, ReactiveRecord};
18///
19/// #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
20/// struct Point {
21///     reactive: ReactiveRecord,
22///     x: i32,
23/// }
24/// reactive_object!(Point);
25///
26/// let first = Point { x: 1, ..Point::default() };
27/// let _ = first.reactive.suppress_change_notifications();
28/// assert_eq!(first, Point { x: 1, ..Point::default() });
29/// assert_eq!(format!("{first:?}"), "Point { reactive: ReactiveRecord, x: 1 }");
30/// ```
31#[derive(Default)]
32pub struct ReactiveRecord {
33    inner: ReactiveObject,
34}
35
36impl ReactiveRecord {
37    /// The part of a reactive record without handlers or state.
38    pub fn new() -> Self {
39        Self { inner: ReactiveObject::new() }
40    }
41}
42
43impl Deref for ReactiveRecord {
44    type Target = ReactiveObject;
45
46    fn deref(&self) -> &ReactiveObject {
47        &self.inner
48    }
49}
50
51impl AsRef<ReactiveObject> for ReactiveRecord {
52    fn as_ref(&self) -> &ReactiveObject {
53        &self.inner
54    }
55}
56
57impl Clone for ReactiveRecord {
58    fn clone(&self) -> Self {
59        Self::new()
60    }
61}
62
63/// The parts of two records are equal: the state is not data (`Equals(ReactiveRecord?)`).
64impl PartialEq for ReactiveRecord {
65    fn eq(&self, _other: &Self) -> bool {
66        true
67    }
68}
69
70impl Eq for ReactiveRecord {}
71
72/// The part adds nothing to the hash of a record (`GetHashCode`).
73impl Hash for ReactiveRecord {
74    fn hash<H: Hasher>(&self, _state: &mut H) {}
75}
76
77/// The part prints no members (`PrintMembers`).
78impl fmt::Debug for ReactiveRecord {
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        f.write_str("ReactiveRecord")
81    }
82}