realm_db_reader/value/mod.rs
1use chrono::{DateTime, Utc};
2
3use crate::table::Row;
4
5mod from;
6mod into;
7
8pub(crate) const ARRAY_VALUE_KEY: &str = "!ARRAY_VALUE";
9
10// Should match [`crate::spec::ColumnType`]
11/// A single value from a Realm database. Represents one row in one column.
12#[derive(Debug, Clone)]
13pub enum Value {
14 /// A signed integer value. Integers may be nullable in Realm, in which case
15 /// they are represented as [`None`].
16 Int(i64),
17 /// A boolean value. Booleans may be nullable in Realm, in which case
18 /// they are represented as [`None`].
19 Bool(bool),
20 /// A string value. Strings may be nullable in Realm, in which case
21 /// they are represented as [`None`].
22 String(String),
23 /// Currently unsupported.
24 #[doc(hidden)]
25 OldStringEnum(String),
26 /// A binary blob value. Binary blobs may be nullable in Realm, in which case
27 /// they are represented as [`None`].
28 Binary(Vec<u8>),
29 /// A subtable value. Tables in Realm may have a column that contains an
30 /// entire table. In that case, upon loading the row, the subtable and all
31 /// its rows are loaded.
32 Table(Vec<Row<'static>>),
33 /// Currently unsupported.
34 #[doc(hidden)]
35 OldMixed,
36 /// Currently unsupported.
37 #[doc(hidden)]
38 OldDateTime,
39 /// A timestamp value, represented using the `chrono` crate. Timestamps may
40 /// be nullable in Realm, in which case they are represented as [`None`].
41 Timestamp(DateTime<Utc>),
42 /// A floating-point value.
43 Float(f32),
44 /// A double-precision floating-point value.
45 Double(f64),
46 /// Currently unsupported.
47 #[doc(hidden)]
48 Reserved4,
49 /// A link to a row in a given table. If the link is null, it is represented
50 /// as [`None`].
51 Link(Link),
52 /// A list of links to rows in a given table. If a row has no links, this
53 /// will be an empty list.
54 LinkList(Vec<Link>),
55 /// A backlink. In cases where table A maintains a link (see [`Link`] or
56 /// [`LinkList`](`Self::LinkList`)), table B maintains a backlink to table
57 /// A. You can use this to navigate back to the parent row in a has-one
58 /// relationship.
59 ///
60 /// Backlinks may be nullable in Realm, in which case they are represented
61 /// as [`None`].
62 ///
63 /// Backlinks are special, as their containing columns are unnamed, and thus
64 /// cannot be retrieved using [`Row::get`](`crate::Row::get`). Instead, you
65 /// can use [`Row::backlinks`](`crate::Row::backlinks`) to retrieve the
66 /// backlinks. See the documentation for
67 /// [`realm_model!`](`crate::realm_model`) for how to incorporate backlinks
68 /// into your model classes.
69 BackLink(Backlink),
70
71 /// A null value.
72 None,
73}
74
75impl Value {
76 /// Returns true if the value is [`None`].
77 pub fn is_none(&self) -> bool {
78 matches!(self, Value::None)
79 }
80}
81
82/// A link to a single row in a given table.
83#[derive(Debug, Clone, Hash, Eq, PartialEq)]
84pub struct Link {
85 /// The table number of the target table, in the Realm
86 /// [`Group`](`crate::Group`).
87 pub target_table_number: usize,
88 /// The row number this link points to.
89 pub row_number: usize,
90}
91
92impl Link {
93 /// Create a new link to a row in a table.
94 pub fn new(target_table_number: usize, row_number: usize) -> Self {
95 Self {
96 target_table_number,
97 row_number,
98 }
99 }
100}
101
102/// A backlink to one or more rows in a given table. This is the opposite end of
103/// a [`Link`]. Note that [`row_numbers`](`Self::row_numbers`) is guaranteed to
104/// be non-empty. An empty backlink would be represented as [`Value::None`].
105#[derive(Debug, Clone, Hash, Eq, PartialEq)]
106pub struct Backlink {
107 /// The table number of the origin table, in the Realm
108 /// [`Group`](`crate::Group`).
109 pub origin_table_number: usize,
110 /// The column number of the origin column, in the
111 /// [`Table`](`crate::Table`).
112 pub origin_column_number: usize,
113 /// The row numbers this backlink points to, i.e. the rows in the origin
114 /// table that have [`Link`]s to this row.
115 pub row_numbers: Vec<usize>,
116}
117
118impl Backlink {
119 pub fn new(
120 origin_table_number: usize,
121 origin_column_number: usize,
122 row_numbers: Vec<usize>,
123 ) -> Self {
124 Self {
125 origin_table_number,
126 origin_column_number,
127 row_numbers,
128 }
129 }
130}