···11+# Rust atproto template
22+33+A simple template
44+for getting started
55+with writing code using [atrium](https://github.com/atrium-rs/atrium) to interact with atproto repos.
66+This is the minimal setup,
77+but we're using the Statusphere lexicon to create some examples that can be used as studs to create your own
88+application.
99+1010+# [atproto_api](./atproto_api)
1111+1212+Holds your rust types created from [lexicon json schema files](./atproto_api/lexicons)
1313+using [esquema-cli](https://github.com/fatfingers23/esquema)
1414+1515+### How to change and setup lexicons
1616+1717+1. Setup and put your lexicon schema files in [./atproto_api/lexicons](/atproto_api/lexicons)
1818+2. Install with `cargo install esquema-cli --locked --git https://github.com/fatfingers23/esquema.git`
1919+3. Run with from root repo `esquema-cli generate local -l atproto_api/lexicons/ -o atproto_api/src/`
2020+4. You now have Rust types for your lexicon schema in [/atproto_api/src](./atproto_api/src)
2121+2222+# [logic](./logic)
2323+2424+This crate holds all your logic for interacting with the atmosphere (jetstream, repos, etc). Can import it into a
2525+backend, WASM, or in our case a CLI.
2626+2727+# [cli](./cli)
2828+2929+This is a binary showcasing how it can run on the backend
3030+`cargo run --bin cli -- --help` for a list of commands. You can also copy [.env.template](./.env.template) and change it
3131+to `.env` to save your handle and app password there.
3232+3333+#[wasm](./wasm)
3434+This is a simple WASM project showcasing the same logic crate as used in the cli binary.
3535+3636+To run make sure you have [Trunk](https://trunkrs.dev/guide/) setup and then run `trunk serve` in the directory
3737+3838+## CLI and WASM Features to showcase examples
3939+4040+All of these features are implemented in the Logic crate and share a lot of code.
4141+JetStream is a bit of an exception and has 2 different implementations.
4242+[Rocketman](https://crates.io/crates/rocketman) for the cli and just a quick and dirty web_sys websocket connection for
4343+the WASM one
4444+4545+- Create a new Statusphere status
4646+- Get your current Statusphere status
4747+- Look up someone's status via handle to show did resolver
4848+- Start a JetStream listener to listen for updates (Includes atrium did resolver via http)
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!Definitions for the `dev` namespace.
33+pub mod baileytownsend;
+3
atproto_api/src/dev/baileytownsend.rs
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!Definitions for the `dev.baileytownsend` namespace.
33+pub mod retrospective;
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!Definitions for the `dev.baileytownsend.retrospective` namespace.
33+pub mod day;
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!Definitions for the `dev.baileytownsend.retrospective.day` namespace.
33+use atrium_api::types::TryFromUnknown;
44+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
55+#[serde(rename_all = "camelCase")]
66+pub struct RecordData {
77+ ///An array of retrospective countables that happened in your day.
88+ pub countables: Vec<Countable>,
99+ ///An array of retrospective events that happened in your day.
1010+ pub events: Vec<Event>,
1111+ ///A text summary of your day, 300 character limit so it can be used as a post as well
1212+ #[serde(skip_serializing_if = "core::option::Option::is_none")]
1313+ pub summary: core::option::Option<String>,
1414+}
1515+pub type Record = atrium_api::types::Object<RecordData>;
1616+impl From<atrium_api::types::Unknown> for RecordData {
1717+ fn from(value: atrium_api::types::Unknown) -> Self {
1818+ Self::try_from_unknown(value).unwrap()
1919+ }
2020+}
2121+///Something that happened in your day that can be counted. Steps, water consumed, etc.
2222+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
2323+#[serde(rename_all = "camelCase")]
2424+pub struct CountableData {
2525+ ///The count for the event. This is the number of times the event happened.
2626+ pub count: i64,
2727+ ///a slugable key for the countable item using underscores instead of spaces. ounces_water, cookies_eaten, etc.
2828+ pub key: String,
2929+}
3030+pub type Countable = atrium_api::types::Object<CountableData>;
3131+///Something that happened in your day. Maybe you read a book, told a funny joke, or went on a fun outing. This is a record of that event.
3232+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
3333+#[serde(rename_all = "camelCase")]
3434+pub struct EventData {
3535+ ///What was the event? Watched a movie, what movie? Went to the beach?
3636+ pub description: String,
3737+ ///a slugable key for the event item using underscores instead of spaces. Like movies_watched, books_read, or restaurants_tried.
3838+ pub key: String,
3939+}
4040+pub type Event = atrium_api::types::Object<EventData>;
+4
atproto_api/src/lib.rs
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+pub mod record;
33+pub mod xyz;
44+pub mod sh;
+35
atproto_api/src/record.rs
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!A collection of known record types.
33+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
44+#[serde(tag = "$type")]
55+pub enum KnownRecord {
66+ #[serde(rename = "sh.tangled.feed.star")]
77+ ShTangledFeedStar(Box<crate::sh::tangled::feed::star::Record>),
88+ #[serde(rename = "xyz.statusphere.status")]
99+ XyzStatusphereStatus(Box<crate::xyz::statusphere::status::Record>),
1010+}
1111+impl From<crate::sh::tangled::feed::star::Record> for KnownRecord {
1212+ fn from(record: crate::sh::tangled::feed::star::Record) -> Self {
1313+ KnownRecord::ShTangledFeedStar(Box::new(record))
1414+ }
1515+}
1616+impl From<crate::sh::tangled::feed::star::RecordData> for KnownRecord {
1717+ fn from(record_data: crate::sh::tangled::feed::star::RecordData) -> Self {
1818+ KnownRecord::ShTangledFeedStar(Box::new(record_data.into()))
1919+ }
2020+}
2121+impl From<crate::xyz::statusphere::status::Record> for KnownRecord {
2222+ fn from(record: crate::xyz::statusphere::status::Record) -> Self {
2323+ KnownRecord::XyzStatusphereStatus(Box::new(record))
2424+ }
2525+}
2626+impl From<crate::xyz::statusphere::status::RecordData> for KnownRecord {
2727+ fn from(record_data: crate::xyz::statusphere::status::RecordData) -> Self {
2828+ KnownRecord::XyzStatusphereStatus(Box::new(record_data.into()))
2929+ }
3030+}
3131+impl Into<atrium_api::types::Unknown> for KnownRecord {
3232+ fn into(self) -> atrium_api::types::Unknown {
3333+ atrium_api::types::TryIntoUnknown::try_into_unknown(&self).unwrap()
3434+ }
3535+}
+3
atproto_api/src/sh.rs
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!Definitions for the `sh` namespace.
33+pub mod tangled;
+3
atproto_api/src/sh/tangled.rs
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!Definitions for the `sh.tangled` namespace.
33+pub mod feed;
+9
atproto_api/src/sh/tangled/feed.rs
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!Definitions for the `sh.tangled.feed` namespace.
33+pub mod star;
44+#[derive(Debug)]
55+pub struct Star;
66+impl atrium_api::types::Collection for Star {
77+ const NSID: &'static str = "sh.tangled.feed.star";
88+ type Record = star::Record;
99+}
+15
atproto_api/src/sh/tangled/feed/star.rs
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!Definitions for the `sh.tangled.feed.star` namespace.
33+use atrium_api::types::TryFromUnknown;
44+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
55+#[serde(rename_all = "camelCase")]
66+pub struct RecordData {
77+ pub created_at: atrium_api::types::string::Datetime,
88+ pub subject: String,
99+}
1010+pub type Record = atrium_api::types::Object<RecordData>;
1111+impl From<atrium_api::types::Unknown> for RecordData {
1212+ fn from(value: atrium_api::types::Unknown) -> Self {
1313+ Self::try_from_unknown(value).unwrap()
1414+ }
1515+}
+3
atproto_api/src/xyz.rs
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!Definitions for the `xyz` namespace.
33+pub mod statusphere;
+9
atproto_api/src/xyz/statusphere.rs
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!Definitions for the `xyz.statusphere` namespace.
33+pub mod status;
44+#[derive(Debug)]
55+pub struct Status;
66+impl atrium_api::types::Collection for Status {
77+ const NSID: &'static str = "xyz.statusphere.status";
88+ type Record = status::Record;
99+}
+15
atproto_api/src/xyz/statusphere/status.rs
···11+// @generated - This file is generated by esquema-codegen (forked from atrium-codegen). DO NOT EDIT.
22+//!Definitions for the `xyz.statusphere.status` namespace.
33+use atrium_api::types::TryFromUnknown;
44+#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq)]
55+#[serde(rename_all = "camelCase")]
66+pub struct RecordData {
77+ pub created_at: atrium_api::types::string::Datetime,
88+ pub status: String,
99+}
1010+pub type Record = atrium_api::types::Object<RecordData>;
1111+impl From<atrium_api::types::Unknown> for RecordData {
1212+ fn from(value: atrium_api::types::Unknown) -> Self {
1313+ Self::try_from_unknown(value).unwrap()
1414+ }
1515+}