parse_rs/types/
common.rs

1use serde::{Deserialize, Serialize};
2
3/// Represents a Pointer to another Parse object.
4/// Pointers are used to create relationships between objects.
5#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
6pub struct Pointer {
7    #[serde(rename = "__type")]
8    pub __type: String, // Should always be "Pointer"
9    #[serde(rename = "className")]
10    pub class_name: String,
11    #[serde(rename = "objectId")]
12    pub object_id: String,
13}
14
15impl Pointer {
16    /// Creates a new Pointer.
17    pub fn new(class_name: impl Into<String>, object_id: impl Into<String>) -> Self {
18        Pointer {
19            __type: "Pointer".to_string(),
20            class_name: class_name.into(),
21            object_id: object_id.into(),
22        }
23    }
24}
25
26/// Represents a Parse Date type, which includes timezone information.
27/// Parse stores dates in UTC.
28#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
29pub struct ParseDate {
30    #[serde(rename = "__type")]
31    pub __type: String, // Should always be "Date"
32    pub iso: String, // ISO 8601 format, e.g., "YYYY-MM-DDTHH:MM:SS.MMMZ"
33}
34
35impl ParseDate {
36    /// Creates a new ParseDate from an ISO 8601 string.
37    /// Note: This does not validate the string format.
38    pub fn new(iso_string: impl Into<String>) -> Self {
39        ParseDate {
40            __type: "Date".to_string(),
41            iso: iso_string.into(),
42        }
43    }
44
45    // TODO: Add a method to create from chrono::DateTime<Utc>
46    // TODO: Add a method to convert to chrono::DateTime<Utc>
47}
48
49/// Represents a relational operation (AddRelation, RemoveRelation).
50#[derive(Debug, Serialize, Clone, PartialEq, Eq)]
51pub struct RelationOp<'a, T>
52where
53    T: Serialize,
54{
55    #[serde(rename = "__op")]
56    op_type: &'static str,
57    objects: &'a [T],
58}
59
60impl<'a, T> RelationOp<'a, T>
61where
62    T: Serialize,
63{
64    pub fn add(objects: &'a [T]) -> Self {
65        RelationOp {
66            op_type: "AddRelation",
67            objects,
68        }
69    }
70
71    pub fn remove(objects: &'a [T]) -> Self {
72        RelationOp {
73            op_type: "RemoveRelation",
74            objects,
75        }
76    }
77}
78
79/// Represents a Parse Relation field on an object.
80/// This indicates a one-to-many or many-to-many relationship.
81/// The actual related objects are typically fetched via a separate query.
82#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
83pub struct ParseRelation {
84    #[serde(rename = "__type")]
85    pub __type: String, // Should always be "Relation"
86    #[serde(rename = "className")]
87    pub class_name: String, // The target class of the relation
88}
89
90impl ParseRelation {
91    /// Creates a new ParseRelation indicator.
92    /// This is mostly for completeness in representing the type, as relations
93    /// are primarily managed through operations and queries.
94    pub fn new(class_name: impl Into<String>) -> Self {
95        ParseRelation {
96            __type: "Relation".to_string(),
97            class_name: class_name.into(),
98        }
99    }
100}
101
102/// Represents different Parse Server API endpoints.
103#[derive(Debug, Clone, PartialEq, Eq)]
104pub enum Endpoint {
105    Classes(String),                 // Class name
106    Objects(String, Option<String>), // Class name, optional objectId
107    Users,
108    UsersLogin,
109    UsersLogout,
110    UsersMe,
111    RequestPasswordReset,
112    Roles,
113    RolesSpecific(String), // Role objectId
114    Schemas,
115    SchemasSpecific(String), // Schema class name
116    Files(String),           // File name
117    Functions(String),       // Function name
118    Config,
119    Aggregate(String), // Class name for aggregate
120                       // Add other endpoints as needed
121}
122
123impl Endpoint {
124    /// Builds the full URL path for the endpoint.
125    pub fn build_url(&self, base_path: &str) -> String {
126        let path = match self {
127            Endpoint::Classes(class_name) => format!("{}/classes/{}", base_path, class_name),
128            Endpoint::Objects(class_name, Some(object_id)) => {
129                format!("{}/classes/{}/{}", base_path, class_name, object_id)
130            }
131            Endpoint::Objects(class_name, None) => format!("{}/classes/{}", base_path, class_name),
132            Endpoint::Users => format!("{}/users", base_path),
133            Endpoint::UsersLogin => format!("{}/login", base_path),
134            Endpoint::UsersLogout => format!("{}/logout", base_path),
135            Endpoint::UsersMe => format!("{}/users/me", base_path),
136            Endpoint::RequestPasswordReset => format!("{}/requestPasswordReset", base_path),
137            Endpoint::Roles => format!("{}/roles", base_path),
138            Endpoint::RolesSpecific(role_id) => format!("{}/roles/{}", base_path, role_id),
139            Endpoint::Schemas => format!("{}/schemas", base_path),
140            Endpoint::SchemasSpecific(class_name) => {
141                format!("{}/schemas/{}", base_path, class_name)
142            }
143            Endpoint::Files(file_name) => format!("{}/files/{}", base_path, file_name),
144            Endpoint::Functions(function_name) => {
145                format!("{}/functions/{}", base_path, function_name)
146            }
147            Endpoint::Config => format!("{}/config", base_path),
148            Endpoint::Aggregate(class_name) => format!("{}/aggregate/{}", base_path, class_name),
149        };
150        // Ensure no double slashes if base_path is just "/"
151        path.replace("//", "/")
152    }
153}
154
155/// Type alias for query parameters, typically a HashMap.
156pub type QueryParams = std::collections::HashMap<String, String>;
157
158/// Represents a generic list of results, commonly returned by find operations.
159#[derive(Debug, Serialize, Deserialize, Clone)]
160pub struct Results<T> {
161    pub results: Vec<T>,
162    // Add other common fields like 'count' if needed for pagination
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub count: Option<i64>,
165}
166
167/// Represents common data in response to update operations.
168#[derive(Debug, Serialize, Deserialize, Clone)]
169pub struct UpdateResponseData {
170    #[serde(rename = "updatedAt")]
171    pub updated_at: String, // ISO 8601 format
172    // Some update operations might return objectId, e.g., if it's a create-or-update
173    #[serde(rename = "objectId", skip_serializing_if = "Option::is_none")]
174    pub object_id: Option<String>,
175}
176
177/// Represents an empty JSON object response, e.g., `{}`.
178/// Useful for operations like DELETE that return a 200 OK with an empty body.
179#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
180pub struct EmptyResponse {}