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
/**
* Represent a set of values, a row of results.
*/
#[derive(Clone, Debug)]
pub struct Tuple<'a> {
result: &'a libpq::Result,
index: usize,
}
impl<'a> Tuple<'a> {
pub(crate) fn from(result: &'a libpq::Result, index: usize) -> Self {
Self { result, index }
}
/**
* Retreive the value of field `name` of the tuple.
*
* # Panics
*
* Panics if `n` is greater than or equal to tuple length.
*/
#[must_use]
pub fn get<T>(&self, name: &str) -> T
where
T: crate::FromSql,
{
self.try_get(name)
.unwrap_or_else(|err| panic!("Unable to retreive '{name}' field: {err}"))
}
/**
* Retreive the value of field `name` of the tuple, or `None` if `n` is
* greater than or equal to the length of the tuple.
*/
pub fn try_get<T>(&self, name: &str) -> crate::Result<T>
where
T: crate::FromSql,
{
let n = match self.result.field_number(name) {
Some(n) => n,
None => return Err(crate::Error::MissingField(name.to_string())),
};
self.try_nth(n)
}
/**
* Retreive the nth field.
*
* # Panics
*
* Panics if `n` is greater than or equal to the length of the tuple.
*/
#[must_use]
pub fn nth<T>(&self, n: usize) -> T
where
T: crate::FromSql,
{
self.try_nth(n)
.unwrap_or_else(|err| panic!("Unable to retreive field {n}: {err}"))
}
/**
* Retreive the nth field, or `None` if `n` is greater than or equal to the
* length of the tuple.
*/
pub fn try_nth<T>(&self, n: usize) -> crate::Result<T>
where
T: crate::FromSql,
{
if n >= self.len() {
return Err(crate::Error::MissingField(n.to_string()));
}
let ty = self.field_type(n);
let format = self.result.field_format(n);
let value = self.result.value(self.index, n);
crate::FromSql::from_sql(&ty, format, value)
}
/**
* Number of field.
*/
#[must_use]
pub fn len(&self) -> usize {
self.result.nfields()
}
/**
* Is the tuple is empty (doesn’t contain field)?
*/
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/**
* Retreive the name of field at position `n`, or `None` if `n` is greater
* than or equal to the length of the tuple.
*/
pub fn field_name(&self, n: usize) -> crate::Result<Option<String>> {
Ok(self.result.field_name(n)?)
}
fn field_type(&self, n: usize) -> crate::pq::Type {
let oid = self.result.field_type(n);
match crate::pq::Type::try_from(oid) {
Ok(ty) => ty,
Err(_) => crate::pq::Type {
oid,
name: "unknow",
descr: "Unknow type",
kind: libpq::types::Kind::Composite,
},
}
}
}
#[cfg(test)]
mod test {
#[test]
fn unknow_field() -> crate::Result {
let conn = crate::test::new_conn()?;
let result = conn.execute("select 1;")?;
assert!(result.get(0).try_nth::<i32>(1).is_err());
Ok(())
}
}