1use serde::{Deserialize, Serialize};
13
14use crate::Method;
15
16use super::{request::ResultReference, Object, RequestParams};
17
18pub trait GetObject: Object {
19 type GetArguments: Default;
20}
21
22#[derive(Debug, Clone, Serialize)]
23pub struct GetRequest<O: GetObject> {
24 #[serde(skip)]
25 method: (Method, usize),
26
27 #[serde(rename = "accountId")]
28 #[serde(skip_serializing_if = "Option::is_none")]
29 account_id: Option<String>,
30
31 #[serde(skip_serializing_if = "Option::is_none")]
32 ids: Option<Vec<String>>,
33
34 #[serde(rename = "#ids")]
35 #[serde(skip_deserializing)]
36 #[serde(skip_serializing_if = "Option::is_none")]
37 ids_ref: Option<ResultReference>,
38
39 #[serde(skip_serializing_if = "Option::is_none")]
40 properties: Option<Vec<O::Property>>,
41
42 #[serde(rename = "#properties")]
43 #[serde(skip_deserializing)]
44 #[serde(skip_serializing_if = "Option::is_none")]
45 properties_ref: Option<ResultReference>,
46
47 #[serde(flatten)]
48 arguments: O::GetArguments,
49}
50
51#[derive(Debug, Clone, Deserialize)]
52pub struct GetResponse<T> {
53 #[serde(rename = "accountId")]
54 account_id: Option<String>,
55
56 state: String,
57
58 list: Vec<T>,
59
60 #[serde(rename = "notFound")]
61 not_found: Vec<String>,
62}
63
64impl<O: GetObject> GetRequest<O> {
65 pub fn new(params: RequestParams) -> Self {
66 GetRequest {
67 account_id: if O::requires_account_id() {
68 params.account_id.into()
69 } else {
70 None
71 },
72 method: (params.method, params.call_id),
73 ids: None,
74 ids_ref: None,
75 properties: None,
76 properties_ref: None,
77 arguments: O::GetArguments::default(),
78 }
79 }
80
81 pub fn account_id(&mut self, account_id: impl Into<String>) -> &mut Self {
82 if O::requires_account_id() {
83 self.account_id = Some(account_id.into());
84 }
85 self
86 }
87
88 pub fn ids<U, V>(&mut self, ids: U) -> &mut Self
89 where
90 U: IntoIterator<Item = V>,
91 V: Into<String>,
92 {
93 self.ids = Some(ids.into_iter().map(|v| v.into()).collect());
94 self.ids_ref = None;
95 self
96 }
97
98 pub fn ids_ref(&mut self, reference: ResultReference) -> &mut Self {
99 self.ids_ref = reference.into();
100 self.ids = None;
101 self
102 }
103
104 pub fn properties(&mut self, properties: impl IntoIterator<Item = O::Property>) -> &mut Self {
105 self.properties = Some(properties.into_iter().collect());
106 self.properties_ref = None;
107 self
108 }
109
110 pub fn properties_ref(&mut self, reference: ResultReference) -> &mut Self {
111 self.properties_ref = Some(reference);
112 self.properties = None;
113 self
114 }
115
116 pub fn arguments(&mut self) -> &mut O::GetArguments {
117 &mut self.arguments
118 }
119
120 pub fn result_reference(&self, property: O::Property) -> ResultReference {
121 ResultReference::new(
122 self.method.0,
123 self.method.1,
124 format!("/list/*/{}", property),
125 )
126 }
127}
128
129impl<O> GetResponse<O> {
130 pub fn account_id(&self) -> Option<&str> {
131 self.account_id.as_deref()
132 }
133
134 pub fn state(&self) -> &str {
135 &self.state
136 }
137
138 pub fn take_state(&mut self) -> String {
139 std::mem::take(&mut self.state)
140 }
141
142 pub fn list(&self) -> &[O] {
143 &self.list
144 }
145
146 pub fn not_found(&self) -> &[String] {
147 &self.not_found
148 }
149
150 pub fn take_list(&mut self) -> Vec<O> {
151 std::mem::take(&mut self.list)
152 }
153 pub fn pop(&mut self) -> Option<O> {
154 self.list.pop()
155 }
156
157 pub fn take_not_found(&mut self) -> Vec<String> {
158 std::mem::take(&mut self.not_found)
159 }
160}