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
use super::*;
use std::borrow::Borrow;
#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Clone, Hash, Copy)]
pub enum CibouletteSortingDirection {
Asc,
Desc,
}
pub fn parse_sorting<'request>(s: &str) -> Vec<(CibouletteSortingDirection, Cow<'request, str>)> {
let mut res: Vec<(CibouletteSortingDirection, Cow<'request, str>)> = Vec::new();
for el in s.split(',') {
if el.starts_with('-') {
res.push((
CibouletteSortingDirection::Desc,
Cow::Owned(el.borrow().split_at(1).1.to_string()),
))
} else if el.starts_with('+') {
res.push((
CibouletteSortingDirection::Asc,
Cow::Owned(el.borrow().split_at(1).1.to_string()),
))
} else {
res.push((
CibouletteSortingDirection::Asc,
Cow::Owned(el.borrow().to_string()),
))
}
}
res
}
pub fn extract_type(
store: &CibouletteStore,
main_type: Arc<CibouletteResourceType>,
direction: CibouletteSortingDirection,
s: Cow<'_, str>,
) -> Result<CibouletteSortingElement, CibouletteError> {
if s.is_empty() {
return Err(CibouletteError::UnknownField(
main_type.name().to_string(),
"<empty>".to_string(),
));
}
let mut el_list: Vec<Cow<'_, str>> = s.split('.').map(Cow::Borrowed).collect();
let field_raw = el_list.pop().unwrap_or_default();
let rel_chain: Vec<CibouletteResourceRelationshipDetails> = match el_list.is_empty() {
true => Vec::new(),
false => CibouletteQueryParametersBuilder::check_relationship_exists(
store,
&main_type,
el_list.as_slice(),
)?,
};
let field = CibouletteQueryParametersBuilder::check_field_exists(
&rel_chain
.last()
.map(|x| x.related_type())
.unwrap_or(&main_type),
field_raw.as_ref(),
)?;
Ok(CibouletteSortingElement {
rel_chain,
direction,
field,
})
}