use azure_core::{fmt::SafeDebug, http::Etag, time::OffsetDateTime};
use serde::{Deserialize, Deserializer, Serialize};
mod account_properties;
mod batch_response;
mod container_properties;
mod cosmos_response;
mod indexing_policy;
mod item_response;
mod resource_response;
mod response_metadata;
mod throughput_properties;
pub(crate) use account_properties::*;
pub use batch_response::BatchResponse;
pub use container_properties::*;
pub(crate) use cosmos_response::CosmosResponse;
pub use indexing_policy::*;
pub use item_response::ItemResponse;
pub use resource_response::ResourceResponse;
pub use response_metadata::CosmosDiagnostics;
pub use throughput_properties::*;
#[doc(inline)]
pub use azure_data_cosmos_driver::models::{
ContainerReference, PartitionKeyDefinition, PartitionKeyKind, PartitionKeyVersion,
};
fn deserialize_cosmos_timestamp<'de, D>(deserializer: D) -> Result<Option<OffsetDateTime>, D::Error>
where
D: Deserializer<'de>,
{
let seconds_since_epoch = Option::<i64>::deserialize(deserializer)?;
match seconds_since_epoch {
None => Ok(None),
Some(seconds) => Ok(Some(OffsetDateTime::from_unix_timestamp(seconds).map_err(
|_| {
use serde::de::Error;
D::Error::invalid_value(
serde::de::Unexpected::Signed(seconds),
&"a valid timestamp",
)
},
)?)),
}
}
#[non_exhaustive]
#[derive(Clone, Default, SafeDebug, Deserialize, Serialize, PartialEq, Eq)]
#[safe(true)]
pub struct SystemProperties {
#[serde(default)]
#[serde(skip_serializing)]
#[serde(rename = "_etag")]
pub etag: Option<Etag>,
#[serde(default)]
#[serde(skip_serializing)]
#[serde(rename = "_self")]
pub self_link: Option<String>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "_rid")]
pub resource_id: Option<String>,
#[serde(default)]
#[serde(rename = "_ts")]
#[serde(skip_serializing)]
#[serde(deserialize_with = "deserialize_cosmos_timestamp")]
pub last_modified: Option<OffsetDateTime>,
}
#[non_exhaustive]
#[derive(Clone, Default, SafeDebug, Deserialize, Serialize, PartialEq, Eq)]
#[safe(true)]
pub struct DatabaseProperties {
pub id: String,
#[serde(flatten)]
pub system_properties: SystemProperties,
}
#[cfg(test)]
mod tests {
use serde::{Deserialize, Serialize};
use time::{Date, Month, OffsetDateTime, Time};
#[cfg(test)]
#[derive(Debug, Deserialize, Serialize)]
struct TimestampHolder {
#[serde(default)]
#[serde(deserialize_with = "super::deserialize_cosmos_timestamp")]
pub ts: Option<OffsetDateTime>,
}
#[test]
pub fn deserialize_timestamp() {
let value: TimestampHolder = serde_json::from_str(r#"{"ts":1729036800}"#).unwrap();
let expected = OffsetDateTime::new_utc(
Date::from_calendar_date(2024, Month::October, 16).unwrap(), Time::MIDNIGHT,
);
assert_eq!(Some(expected), value.ts);
}
#[test]
pub fn deserialize_missing_timestamp() {
let value: TimestampHolder = serde_json::from_str(r#"{}"#).unwrap();
assert_eq!(None, value.ts);
}
#[test]
pub fn deserialize_null_timestamp() {
let value: TimestampHolder = serde_json::from_str(r#"{"ts":null}"#).unwrap();
assert_eq!(None, value.ts);
}
}