paperless_api/
document_query.rs1use crate::{
4 document::ArchiveSerialNumber,
5 id::{CorrespondentId, TagId},
6};
7
8#[derive(Default)]
10pub struct DocumentQueryBuilder {
11 archive_serial_number: Option<ArchiveSerialNumber>,
12 correspondent_id_in: Option<Vec<CorrespondentId>>,
13 correspondent_name_icontains: Option<String>,
14 content_icontains: Option<String>,
15 title_icontains: Option<String>,
16 tags_id_in: Option<Vec<TagId>>,
17 pub(crate) full_content: bool,
18 full_permissions: bool,
19}
20
21pub struct DocumentQuery {
23 pub(crate) query: Vec<(&'static str, String)>,
24}
25
26pub(crate) const QUERY_PARAM_FULL_PERMISSIONS: &str = "full_perms";
27pub(crate) const QUERY_PARAM_TRUNCATE_CONTENT: &str = "truncate_content";
28const QUERY_PARAM_TAGS_ID_IN: &str = "tags__id__in";
29const QUERY_PARAM_ARCHIVE_SERIAL_NUMBER: &str = "archive_serial_number";
30const QUERY_PARAM_CORRESPONDENT_ID_IN: &str = "correspondent__id__in";
31const QUERY_PARAM_CORRESPONDENT_NAME_ICONTAINS: &str = "correspondent__name__icontains";
32const QUERY_PARAM_CONTENT_ICONTAINS: &str = "content__icontains";
33const QUERY_PARAM_TITLE_ICONTAINS: &str = "title__icontains";
34
35impl DocumentQueryBuilder {
36 #[must_use]
38 pub fn archive_serial_number(mut self, archive_serial_number: ArchiveSerialNumber) -> Self {
39 self.archive_serial_number = Some(archive_serial_number);
40 self
41 }
42
43 #[must_use]
45 pub fn correspondent_id_in(mut self, correspondent_id_in: Vec<CorrespondentId>) -> Self {
46 self.correspondent_id_in = Some(correspondent_id_in);
47 self
48 }
49
50 #[must_use]
52 pub fn correspondent_name_icontains(mut self, correspondent_name_icontains: String) -> Self {
53 self.correspondent_name_icontains = Some(correspondent_name_icontains);
54 self
55 }
56
57 #[must_use]
59 pub fn content_icontains(mut self, content_icontains: String) -> Self {
60 self.content_icontains = Some(content_icontains);
61 self
62 }
63
64 #[must_use]
66 pub fn title_icontains(mut self, title_icontains: String) -> Self {
67 self.title_icontains = Some(title_icontains);
68 self
69 }
70
71 #[must_use]
73 pub fn tags_id_in(mut self, tags_id_in: Vec<TagId>) -> Self {
74 self.tags_id_in = Some(tags_id_in);
75 self
76 }
77
78 #[must_use]
80 pub fn full_content(mut self, full_content: bool) -> Self {
81 self.full_content = full_content;
82 self
83 }
84
85 #[must_use]
87 pub fn full_permissions(mut self, full_permissions: bool) -> Self {
88 self.full_permissions = full_permissions;
89 self
90 }
91
92 #[must_use]
94 pub fn build(self) -> DocumentQuery {
95 let mut query = vec![];
96
97 if let Some(archive_serial_number) = self.archive_serial_number {
98 query.push((
99 QUERY_PARAM_ARCHIVE_SERIAL_NUMBER,
100 archive_serial_number.0.to_string(),
101 ));
102 }
103
104 if let Some(correspondent_id_in) = self.correspondent_id_in {
105 query.push((
106 QUERY_PARAM_CORRESPONDENT_ID_IN,
107 correspondent_id_in
108 .iter()
109 .map(|id| id.0.to_string())
110 .collect::<Vec<_>>()
111 .join(","),
112 ));
113 }
114
115 if let Some(correspondent_name_icontains) = self.correspondent_name_icontains {
116 query.push((
117 QUERY_PARAM_CORRESPONDENT_NAME_ICONTAINS,
118 correspondent_name_icontains,
119 ));
120 }
121
122 if let Some(content_icontains) = self.content_icontains {
123 query.push((QUERY_PARAM_CONTENT_ICONTAINS, content_icontains));
124 }
125
126 if let Some(title_icontains) = self.title_icontains {
127 query.push((QUERY_PARAM_TITLE_ICONTAINS, title_icontains));
128 }
129
130 if let Some(tags_id_in) = self.tags_id_in {
131 query.push((
132 QUERY_PARAM_TAGS_ID_IN,
133 tags_id_in
134 .iter()
135 .map(|id| id.0.to_string())
136 .collect::<Vec<_>>()
137 .join(","),
138 ));
139 }
140
141 if !self.full_content {
142 query.push((QUERY_PARAM_TRUNCATE_CONTENT, "true".to_string()));
143 }
144
145 if self.full_permissions {
146 query.push((QUERY_PARAM_FULL_PERMISSIONS, "true".to_string()));
147 }
148
149 DocumentQuery { query }
150 }
151}