1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
use crate::{
types::{Entry, Field, ID, UUID},
Error,
};
use std::{iter::Iterator, string::ToString};
/// Item in a list. Wrapper for Entry that includes field getters for business values.
#[derive(Debug)]
pub struct Item<'li> {
entry: Entry,
list_name: &'li str,
list_id: ID,
fields: &'li [Field],
}
impl<'li> Item<'li> {
/// Constructs new item
pub(crate) fn new(
entry: Entry,
list_name: &'li str,
list_id: ID,
fields: &'li [Field],
) -> Self {
Self {
entry,
list_name,
list_id,
fields,
}
}
/// Returns reference to the inner entry. Also available with deref.
pub fn as_entry(&self) -> &Entry {
&self.entry
}
/// Return entry id
pub fn get_id(&self) -> ID {
self.entry.id
}
/// Returns entry uuid
pub fn get_uuid(&self) -> &UUID {
&self.entry.uuid
}
/// Returns field (definition) given its name, id, or uuid
pub fn get_field(&self, field_id: &str) -> Result<&Field, Error> {
self.fields
.iter()
.find(|e| e.name == field_id || e.uuid == field_id || e.id.to_string() == field_id)
.ok_or_else(|| {
Error::Other(format!(
"Invalid field '{}' in list {}",
field_id, self.list_name,
))
})
}
/// Returns value of text field. or None if not defined
/// fname parameter may be field name, id, or uuid
pub fn get_text_value(&self, fname: &str) -> Result<Option<&str>, Error> {
self.get_field(fname)
.map(|field| self.entry.get_text_value(&field.uuid))?
}
/// Returns value of integer field as i64. or None if not defined
/// fname parameter may be field name, id, or uuid
pub fn get_int_value(&self, fname: &str) -> Result<Option<i64>, Error> {
self.get_field(fname)
.map(|field| self.entry.get_int_value(&field.uuid))?
}
/// Returns value of float field. or None if not defined
/// fname parameter may be field name, id, or uuid
pub fn get_float_value(&self, fname: &str) -> Result<Option<f64>, Error> {
self.get_field(fname)
.map(|field| self.entry.get_float_value(&field.uuid))?
}
/// Returns value of date field. or None if not defined
/// fname parameter may be field name, id, or uuid
pub fn get_date_value(&self, fname: &str) -> Result<Option<&str>, Error> {
self.get_field(fname)
.map(|field| self.entry.get_date_value(&field.uuid))?
}
/// Returns display names of persons in field value.
/// fname parameter may be field name, id, or uuid
pub fn get_person_names(&self, fname: &str) -> Result<Vec<&str>, Error> {
self.get_field(fname)
.map(|field| self.entry.get_person_names(&field.uuid))
}
/// Returns IDs of persons in field value.
/// fname parameter may be field name, id, or uuid
pub fn get_person_ids(&self, fname: &str) -> Result<Vec<ID>, Error> {
self.get_field(fname)
.map(|field| self.entry.get_person_ids(&field.uuid))
}
/// Returns uuids of referred objects in field value.
/// fname parameter may be field name, id, or uuid
pub fn get_references(&self, fname: &str) -> Result<Vec<&str>, Error> {
self.get_field(fname)
.map(|field| self.entry.get_references(&field.uuid))
}
/// Returns array of choice (aka label/category) values.
/// Array could be empty if none are selected
pub fn get_choices(&self, fname: &str) -> Result<Vec<&str>, Error> {
self.get_field(fname)
.map(|field| self.entry.get_category_names(&field.uuid))
}
/// Returns single choice value, or None if unselected.
/// This will return an error if multiple values are selected, which would mean
/// that the programmer believed the field had multiple-choices disabled,
/// and they were enabled in the UI.
pub fn get_choice(&self, fname: &str) -> Result<Option<&str>, Error> {
let names = self.get_choices(fname)?;
match names.len() {
0 => Ok(None),
1 => Ok(Some(names.get(0).unwrap())),
_ => Err(Error::MultiCategory(
"Configuration error: label field not expected to contain multiple values"
.to_string(),
fname.to_string(),
)),
}
}
}
impl<'li> std::ops::Deref for Item<'li> {
type Target = Entry;
fn deref(&self) -> &Entry {
&self.entry
}
}