use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize)] pub struct QueryRequest { #[serde(rename = "accountId")] account_id: String, #[serde(rename = "filter")] #[serde(skip_serializing_if = "Option::is_none")] filter: Option>, #[serde(rename = "sort")] #[serde(skip_serializing_if = "Option::is_none")] sort: Option>>, #[serde(rename = "position")] #[serde(skip_serializing_if = "Option::is_none")] position: Option, #[serde(rename = "anchor")] #[serde(skip_serializing_if = "Option::is_none")] anchor: Option, #[serde(rename = "anchorOffset")] #[serde(skip_serializing_if = "Option::is_none")] anchor_offset: Option, #[serde(rename = "limit")] #[serde(skip_serializing_if = "Option::is_none")] limit: Option, #[serde(rename = "calculateTotal")] #[serde(skip_serializing_if = "Option::is_none")] calculate_total: Option, #[serde(flatten)] arguments: A, } #[derive(Debug, Clone, Serialize)] #[serde(untagged)] pub enum Filter { FilterOperator(FilterOperator), FilterCondition(T), } #[derive(Debug, Clone, Serialize)] pub struct FilterOperator { operator: Operator, conditions: Vec>, } #[derive(Debug, Clone, Serialize)] pub enum Operator { #[serde(rename = "AND")] And, #[serde(rename = "OR")] Or, #[serde(rename = "NOT")] Not, } #[derive(Debug, Clone, Serialize)] pub struct Comparator { #[serde(rename = "isAscending")] is_ascending: bool, #[serde(skip_serializing_if = "Option::is_none")] collation: Option, #[serde(flatten)] arguments: A, } #[derive(Debug, Clone, Deserialize)] pub struct QueryResponse { #[serde(rename = "accountId")] account_id: String, #[serde(rename = "queryState")] query_state: String, #[serde(rename = "canCalculateChanges")] can_calculate_changes: Option, #[serde(rename = "position")] position: i32, #[serde(rename = "ids")] ids: Vec, #[serde(rename = "total")] total: Option, #[serde(rename = "limit")] limit: Option, } impl QueryRequest { pub fn new(account_id: String) -> Self { QueryRequest { account_id, filter: None, sort: None, position: None, anchor: None, anchor_offset: None, limit: None, calculate_total: None, arguments: A::default(), } } pub fn account_id(&mut self, account_id: impl Into) -> &mut Self { self.account_id = account_id.into(); self } pub fn filter(&mut self, filter: impl Into>) -> &mut Self { self.filter = Some(filter.into()); self } pub fn sort(&mut self, sort: impl IntoIterator>) -> &mut Self { self.sort = Some(sort.into_iter().collect()); self } pub fn position(&mut self, position: i32) -> &mut Self { self.position = position.into(); self } pub fn anchor(&mut self, anchor: impl Into) -> &mut Self { self.anchor = Some(anchor.into()); self } pub fn anchor_offset(&mut self, anchor_offset: i32) -> &mut Self { self.anchor_offset = anchor_offset.into(); self } pub fn limit(&mut self, limit: usize) -> &mut Self { self.limit = Some(limit); self } pub fn arguments(&mut self) -> &mut A { &mut self.arguments } } impl QueryResponse { pub fn account_id(&self) -> &str { &self.account_id } pub fn ids(&self) -> &[String] { &self.ids } pub fn total(&self) -> Option { self.total } pub fn limit(&self) -> Option { self.limit } pub fn position(&self) -> i32 { self.position } pub fn query_state(&self) -> &str { &self.query_state } pub fn can_calculate_changes(&self) -> bool { self.can_calculate_changes.unwrap_or(false) } } impl Comparator { pub fn new(arguments: A) -> Self { Comparator { is_ascending: true, collation: None, arguments, } } pub fn is_ascending(mut self, is_ascending: bool) -> Self { self.is_ascending = is_ascending; self } pub fn collation(mut self, collation: String) -> Self { self.collation = Some(collation); self } } impl From> for Filter { fn from(filter: FilterOperator) -> Self { Filter::FilterOperator(filter) } } impl From for Filter { fn from(filter: T) -> Self { Filter::FilterCondition(filter) } } impl Filter { pub fn and(conditions: U) -> Self where U: IntoIterator, V: Into>, { Filter::FilterOperator(FilterOperator { operator: Operator::And, conditions: conditions.into_iter().map(|t| t.into()).collect(), }) } pub fn or(conditions: U) -> Self where U: IntoIterator, V: Into>, { Filter::FilterOperator(FilterOperator { operator: Operator::Or, conditions: conditions.into_iter().map(|t| t.into()).collect(), }) } pub fn not(conditions: U) -> Self where U: IntoIterator, V: Into>, { Filter::FilterOperator(FilterOperator { operator: Operator::Not, conditions: conditions.into_iter().map(|t| t.into()).collect(), }) } }