autofill/db/models/
address.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2* License, v. 2.0. If a copy of the MPL was not distributed with this
3* file, You can obtain one at http://mozilla.org/MPL/2.0/.
4*/
5
6use super::Metadata;
7use rusqlite::Row;
8use sync_guid::Guid;
9
10// UpdatableAddressFields contains the fields we support for creating a new
11// address or updating an existing one. It's missing the guid, our "internal"
12// meta fields (such as the change counter) and "external" meta fields
13// (such as timeCreated) because it doesn't make sense for these things to be
14// specified as an item is created - any meta fields which can be updated
15// have special methods for doing so.
16#[derive(Debug, Clone, Default)]
17pub struct UpdatableAddressFields {
18    pub name: String,
19    pub organization: String,
20    pub street_address: String,
21    pub address_level3: String,
22    pub address_level2: String,
23    pub address_level1: String,
24    pub postal_code: String,
25    pub country: String,
26    pub tel: String,
27    pub email: String,
28}
29
30// "Address" is what we return to consumers and has most of the metadata.
31#[derive(Debug, Clone, Hash, PartialEq, Eq, Default)]
32pub struct Address {
33    pub guid: String,
34    pub name: String,
35    pub organization: String,
36    pub street_address: String,
37    pub address_level3: String,
38    pub address_level2: String,
39    pub address_level1: String,
40    pub postal_code: String,
41    pub country: String,
42    pub tel: String,
43    pub email: String,
44    // We expose some of the metadata
45    pub time_created: i64,
46    pub time_last_used: Option<i64>,
47    pub time_last_modified: i64,
48    pub times_used: i64,
49}
50
51// This is used to "externalize" an address, suitable for handing back to
52// consumers.
53impl From<InternalAddress> for Address {
54    fn from(ia: InternalAddress) -> Self {
55        Address {
56            guid: ia.guid.to_string(),
57            name: ia.name,
58            organization: ia.organization,
59            street_address: ia.street_address,
60            address_level3: ia.address_level3,
61            address_level2: ia.address_level2,
62            address_level1: ia.address_level1,
63            postal_code: ia.postal_code,
64            country: ia.country,
65            tel: ia.tel,
66            email: ia.email,
67            // note we can't use u64 in uniffi
68            time_created: u64::from(ia.metadata.time_created) as i64,
69            time_last_used: if ia.metadata.time_last_used.0 == 0 {
70                None
71            } else {
72                Some(ia.metadata.time_last_used.0 as i64)
73            },
74            time_last_modified: u64::from(ia.metadata.time_last_modified) as i64,
75            times_used: ia.metadata.times_used,
76        }
77    }
78}
79
80// An "internal" address is used by the public APIs and by sync. No `PartialEq`
81// because it's impossible to do it meaningfully for credit-cards and we'd like
82// to keep the API symmetric
83#[derive(Default, Debug, Clone)]
84pub struct InternalAddress {
85    pub guid: Guid,
86    pub name: String,
87    pub organization: String,
88    pub street_address: String,
89    pub address_level3: String,
90    pub address_level2: String,
91    pub address_level1: String,
92    pub postal_code: String,
93    pub country: String,
94    pub tel: String,
95    pub email: String,
96    pub metadata: Metadata,
97}
98
99impl InternalAddress {
100    pub fn from_row(row: &Row<'_>) -> Result<InternalAddress, rusqlite::Error> {
101        Ok(Self {
102            guid: row.get("guid")?,
103            name: row.get("name")?,
104            organization: row.get("organization")?,
105            street_address: row.get("street_address")?,
106            address_level3: row.get("address_level3")?,
107            address_level2: row.get("address_level2")?,
108            address_level1: row.get("address_level1")?,
109            postal_code: row.get("postal_code")?,
110            country: row.get("country")?,
111            tel: row.get("tel")?,
112            email: row.get("email")?,
113            metadata: Metadata {
114                time_created: row.get("time_created")?,
115                time_last_used: row.get("time_last_used")?,
116                time_last_modified: row.get("time_last_modified")?,
117                times_used: row.get("times_used")?,
118                sync_change_counter: row.get("sync_change_counter")?,
119            },
120        })
121    }
122}