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}