#[allow(unused_imports)]
use alloc::collections::BTreeMap;
#[allow(unused_imports)]
use core::marker::PhantomData;
use jacquard_common::{BosStr, CowStr, DefaultStr, FromStaticStr};
#[allow(unused_imports)]
use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
use jacquard_common::deps::smol_str::SmolStr;
use jacquard_common::types::blob::BlobRef;
use jacquard_common::types::collection::{Collection, RecordError};
use jacquard_common::types::string::{AtUri, Cid, Datetime};
use jacquard_common::types::uri::{RecordUri, UriError};
use jacquard_common::types::value::Data;
use jacquard_common::xrpc::XrpcResp;
use jacquard_derive::{IntoStatic, lexicon};
use jacquard_lexicon::lexicon::LexiconDoc;
use jacquard_lexicon::schema::LexiconSchema;
use crate::social_pace::feed::ActivityType;
use crate::social_pace::feed::Split;
#[allow(unused_imports)]
use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(
rename_all = "camelCase",
rename = "social.pace.feed.activity",
tag = "$type",
bound(deserialize = "S: Deserialize<'de> + BosStr")
)]
pub struct Activity<S: BosStr = DefaultStr> {
#[serde(skip_serializing_if = "Option::is_none")]
pub calories: Option<i64>,
pub created_at: Datetime,
#[serde(skip_serializing_if = "Option::is_none")]
pub distance: Option<S>,
#[serde(skip_serializing_if = "Option::is_none")]
pub distance_units: Option<S>,
pub ended_at: Datetime,
#[serde(skip_serializing_if = "Option::is_none")]
pub route: Option<BlobRef<S>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub splits: Option<Vec<Split<S>>>,
pub started_at: Datetime,
#[serde(skip_serializing_if = "Option::is_none")]
pub steps: Option<i64>,
pub r#type: ActivityType<S>,
#[serde(flatten, default, skip_serializing_if = "Option::is_none")]
pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase")]
pub struct ActivityGetRecordOutput<S: BosStr = DefaultStr> {
#[serde(skip_serializing_if = "Option::is_none")]
pub cid: Option<Cid<S>>,
pub uri: AtUri<S>,
pub value: Activity<S>,
}
impl<S: BosStr> Activity<S> {
pub fn uri(uri: S) -> Result<RecordUri<S, ActivityRecord>, UriError> {
RecordUri::try_from_uri(AtUri::new(uri)?)
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ActivityRecord;
impl XrpcResp for ActivityRecord {
const NSID: &'static str = "social.pace.feed.activity";
const ENCODING: &'static str = "application/json";
type Output<S: BosStr> = ActivityGetRecordOutput<S>;
type Err = RecordError;
}
impl<S: BosStr> From<ActivityGetRecordOutput<S>> for Activity<S> {
fn from(output: ActivityGetRecordOutput<S>) -> Self {
output.value
}
}
impl<S: BosStr> Collection for Activity<S> {
const NSID: &'static str = "social.pace.feed.activity";
type Record = ActivityRecord;
}
impl Collection for ActivityRecord {
const NSID: &'static str = "social.pace.feed.activity";
type Record = ActivityRecord;
}
impl<S: BosStr> LexiconSchema for Activity<S> {
fn nsid() -> &'static str {
"social.pace.feed.activity"
}
fn def_name() -> &'static str {
"main"
}
fn lexicon_doc() -> LexiconDoc<'static> {
lexicon_doc_social_pace_feed_activity()
}
fn validate(&self) -> Result<(), ConstraintError> {
if let Some(ref value) = self.distance_units {
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 10usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("distance_units"),
max: 10usize,
actual: <str>::len(value.as_ref()),
});
}
}
if let Some(ref value) = self.route {
{
let mime = value.blob().mime_type.as_str();
let accepted: &[&str] = &["application/vnd.garmin.tcx+xml", "application/gpx+xml."];
let matched = accepted.iter().any(|pattern| {
if *pattern == "*/*" {
true
} else if pattern.ends_with("/*") {
let prefix = &pattern[..pattern.len() - 2];
mime.starts_with(prefix) && mime.as_bytes().get(prefix.len()) == Some(&b'/')
} else {
mime == *pattern
}
});
if !matched {
return Err(ConstraintError::BlobMimeTypeNotAccepted {
path: ValidationPath::from_field("route"),
accepted: vec![
"application/vnd.garmin.tcx+xml".to_string(),
"application/gpx+xml.".to_string(),
],
actual: mime.to_string(),
});
}
}
}
Ok(())
}
}
pub mod activity_state {
pub use crate::builder_types::{IsSet, IsUnset, Set, Unset};
#[allow(unused)]
use ::core::marker::PhantomData;
mod sealed {
pub trait Sealed {}
}
pub trait State: sealed::Sealed {
type Type;
type CreatedAt;
type StartedAt;
type EndedAt;
}
pub struct Empty(());
impl sealed::Sealed for Empty {}
impl State for Empty {
type Type = Unset;
type CreatedAt = Unset;
type StartedAt = Unset;
type EndedAt = Unset;
}
pub struct SetType<St: State = Empty>(PhantomData<fn() -> St>);
impl<St: State> sealed::Sealed for SetType<St> {}
impl<St: State> State for SetType<St> {
type Type = Set<members::r#type>;
type CreatedAt = St::CreatedAt;
type StartedAt = St::StartedAt;
type EndedAt = St::EndedAt;
}
pub struct SetCreatedAt<St: State = Empty>(PhantomData<fn() -> St>);
impl<St: State> sealed::Sealed for SetCreatedAt<St> {}
impl<St: State> State for SetCreatedAt<St> {
type Type = St::Type;
type CreatedAt = Set<members::created_at>;
type StartedAt = St::StartedAt;
type EndedAt = St::EndedAt;
}
pub struct SetStartedAt<St: State = Empty>(PhantomData<fn() -> St>);
impl<St: State> sealed::Sealed for SetStartedAt<St> {}
impl<St: State> State for SetStartedAt<St> {
type Type = St::Type;
type CreatedAt = St::CreatedAt;
type StartedAt = Set<members::started_at>;
type EndedAt = St::EndedAt;
}
pub struct SetEndedAt<St: State = Empty>(PhantomData<fn() -> St>);
impl<St: State> sealed::Sealed for SetEndedAt<St> {}
impl<St: State> State for SetEndedAt<St> {
type Type = St::Type;
type CreatedAt = St::CreatedAt;
type StartedAt = St::StartedAt;
type EndedAt = Set<members::ended_at>;
}
#[allow(non_camel_case_types)]
pub mod members {
pub struct r#type(());
pub struct created_at(());
pub struct started_at(());
pub struct ended_at(());
}
}
pub struct ActivityBuilder<S: BosStr, St: activity_state::State> {
_state: PhantomData<fn() -> St>,
_fields: (
Option<i64>,
Option<Datetime>,
Option<S>,
Option<S>,
Option<Datetime>,
Option<BlobRef<S>>,
Option<Vec<Split<S>>>,
Option<Datetime>,
Option<i64>,
Option<ActivityType<S>>,
),
_type: PhantomData<fn() -> S>,
}
impl<S: BosStr> Activity<S> {
pub fn new() -> ActivityBuilder<S, activity_state::Empty> {
ActivityBuilder::new()
}
}
impl<S: BosStr> ActivityBuilder<S, activity_state::Empty> {
pub fn new() -> Self {
ActivityBuilder {
_state: PhantomData,
_fields: (None, None, None, None, None, None, None, None, None, None),
_type: PhantomData,
}
}
}
impl<S: BosStr, St: activity_state::State> ActivityBuilder<S, St> {
pub fn calories(mut self, value: impl Into<Option<i64>>) -> Self {
self._fields.0 = value.into();
self
}
pub fn maybe_calories(mut self, value: Option<i64>) -> Self {
self._fields.0 = value;
self
}
}
impl<S: BosStr, St> ActivityBuilder<S, St>
where
St: activity_state::State,
St::CreatedAt: activity_state::IsUnset,
{
pub fn created_at(
mut self,
value: impl Into<Datetime>,
) -> ActivityBuilder<S, activity_state::SetCreatedAt<St>> {
self._fields.1 = Option::Some(value.into());
ActivityBuilder {
_state: PhantomData,
_fields: self._fields,
_type: PhantomData,
}
}
}
impl<S: BosStr, St: activity_state::State> ActivityBuilder<S, St> {
pub fn distance(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.2 = value.into();
self
}
pub fn maybe_distance(mut self, value: Option<S>) -> Self {
self._fields.2 = value;
self
}
}
impl<S: BosStr, St: activity_state::State> ActivityBuilder<S, St> {
pub fn distance_units(mut self, value: impl Into<Option<S>>) -> Self {
self._fields.3 = value.into();
self
}
pub fn maybe_distance_units(mut self, value: Option<S>) -> Self {
self._fields.3 = value;
self
}
}
impl<S: BosStr, St> ActivityBuilder<S, St>
where
St: activity_state::State,
St::EndedAt: activity_state::IsUnset,
{
pub fn ended_at(
mut self,
value: impl Into<Datetime>,
) -> ActivityBuilder<S, activity_state::SetEndedAt<St>> {
self._fields.4 = Option::Some(value.into());
ActivityBuilder {
_state: PhantomData,
_fields: self._fields,
_type: PhantomData,
}
}
}
impl<S: BosStr, St: activity_state::State> ActivityBuilder<S, St> {
pub fn route(mut self, value: impl Into<Option<BlobRef<S>>>) -> Self {
self._fields.5 = value.into();
self
}
pub fn maybe_route(mut self, value: Option<BlobRef<S>>) -> Self {
self._fields.5 = value;
self
}
}
impl<S: BosStr, St: activity_state::State> ActivityBuilder<S, St> {
pub fn splits(mut self, value: impl Into<Option<Vec<Split<S>>>>) -> Self {
self._fields.6 = value.into();
self
}
pub fn maybe_splits(mut self, value: Option<Vec<Split<S>>>) -> Self {
self._fields.6 = value;
self
}
}
impl<S: BosStr, St> ActivityBuilder<S, St>
where
St: activity_state::State,
St::StartedAt: activity_state::IsUnset,
{
pub fn started_at(
mut self,
value: impl Into<Datetime>,
) -> ActivityBuilder<S, activity_state::SetStartedAt<St>> {
self._fields.7 = Option::Some(value.into());
ActivityBuilder {
_state: PhantomData,
_fields: self._fields,
_type: PhantomData,
}
}
}
impl<S: BosStr, St: activity_state::State> ActivityBuilder<S, St> {
pub fn steps(mut self, value: impl Into<Option<i64>>) -> Self {
self._fields.8 = value.into();
self
}
pub fn maybe_steps(mut self, value: Option<i64>) -> Self {
self._fields.8 = value;
self
}
}
impl<S: BosStr, St> ActivityBuilder<S, St>
where
St: activity_state::State,
St::Type: activity_state::IsUnset,
{
pub fn r#type(
mut self,
value: impl Into<ActivityType<S>>,
) -> ActivityBuilder<S, activity_state::SetType<St>> {
self._fields.9 = Option::Some(value.into());
ActivityBuilder {
_state: PhantomData,
_fields: self._fields,
_type: PhantomData,
}
}
}
impl<S: BosStr, St> ActivityBuilder<S, St>
where
St: activity_state::State,
St::Type: activity_state::IsSet,
St::CreatedAt: activity_state::IsSet,
St::StartedAt: activity_state::IsSet,
St::EndedAt: activity_state::IsSet,
{
pub fn build(self) -> Activity<S> {
Activity {
calories: self._fields.0,
created_at: self._fields.1.unwrap(),
distance: self._fields.2,
distance_units: self._fields.3,
ended_at: self._fields.4.unwrap(),
route: self._fields.5,
splits: self._fields.6,
started_at: self._fields.7.unwrap(),
steps: self._fields.8,
r#type: self._fields.9.unwrap(),
extra_data: Default::default(),
}
}
pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> Activity<S> {
Activity {
calories: self._fields.0,
created_at: self._fields.1.unwrap(),
distance: self._fields.2,
distance_units: self._fields.3,
ended_at: self._fields.4.unwrap(),
route: self._fields.5,
splits: self._fields.6,
started_at: self._fields.7.unwrap(),
steps: self._fields.8,
r#type: self._fields.9.unwrap(),
extra_data: Some(extra_data),
}
}
}
fn lexicon_doc_social_pace_feed_activity() -> LexiconDoc<'static> {
use alloc::collections::BTreeMap;
#[allow(unused_imports)]
use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
use jacquard_lexicon::lexicon::*;
LexiconDoc {
lexicon: Lexicon::Lexicon1,
id: CowStr::new_static("social.pace.feed.activity"),
defs: {
let mut map = BTreeMap::new();
map.insert(
SmolStr::new_static("main"),
LexUserType::Record(LexRecord {
description: Some(
CowStr::new_static(
"A recording of an activity. Like running, walking, lifting weights, etc. Helpful to create the rkey tid from the start time and clock id 23 so you can upsert easily.",
),
),
key: Some(CowStr::new_static("tid")),
record: LexRecordRecord::Object(LexObject {
required: Some(
vec![
SmolStr::new_static("startedAt"),
SmolStr::new_static("endedAt"), SmolStr::new_static("type"),
SmolStr::new_static("createdAt")
],
),
properties: {
#[allow(unused_mut)]
let mut map = BTreeMap::new();
map.insert(
SmolStr::new_static("calories"),
LexObjectProperty::Integer(LexInteger {
..Default::default()
}),
);
map.insert(
SmolStr::new_static("createdAt"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("When the activity was created"),
),
format: Some(LexStringFormat::Datetime),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("distance"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"The distance covered during the activity, if any. This is a string to allow for float values. pace.social support is in feet and meters.",
),
),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("distanceUnits"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"The units used for distance measurement.",
),
),
max_length: Some(10usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("endedAt"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("When the activity ended."),
),
format: Some(LexStringFormat::Datetime),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("route"),
LexObjectProperty::Blob(LexBlob { ..Default::default() }),
);
map.insert(
SmolStr::new_static("splits"),
LexObjectProperty::Array(LexArray {
description: Some(
CowStr::new_static("Array of splits if any."),
),
items: LexArrayItem::Ref(LexRef {
r#ref: CowStr::new_static("social.pace.feed.defs#split"),
..Default::default()
}),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("startedAt"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("When the activity was started."),
),
format: Some(LexStringFormat::Datetime),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("steps"),
LexObjectProperty::Integer(LexInteger {
..Default::default()
}),
);
map.insert(
SmolStr::new_static("type"),
LexObjectProperty::Ref(LexRef {
r#ref: CowStr::new_static(
"social.pace.feed.defs#activityType",
),
..Default::default()
}),
);
map
},
..Default::default()
}),
..Default::default()
}),
);
map
},
..Default::default()
}
}