dialtone_common 0.1.0

Dialtone Common Code
Documentation
use crate::ap::image_attr::ImageAttributes;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone)]
pub enum ActorType {
   Application,
   Group,
   Organization,
   Person,
   Service,
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct Actor {
    #[serde(rename = "type")]
    pub ap_type: ActorType,

    pub id: String,

    #[serde(rename = "preferredUsername")]
    pub preferred_user_name: String,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub summary: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub icon: Option<ImageAttributes>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub image: Option<ImageAttributes>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub following: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub followers: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub liked: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub likes: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub inbox: Option<String>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub outbox: Option<String>,

    #[serde(rename = "publicKey")]
    pub public_key: PublicKey,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub endpoints: Option<Endpoints>,
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct Endpoints {
    #[serde(rename = "sharedInbox")]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub shared_inbox: Option<String>,
}

#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct PublicKey {
    pub id: String,

    pub owner: String,

    #[serde(rename = "publicKeyPem")]
    pub public_key_pem: String,
}

#[cfg(test)]
mod actor_tests {
    use super::*;
    use crate::ap::image_attr::ImageAttributes;

    #[test]
    fn roundtrip_serde() {
        let a = super::Actor {
            ap_type: ActorType::Person,
            id: "http://example.com/foo".to_string(),
            preferred_user_name: "foo".to_string(),
            name: Option::from("foooo chillin".to_string()),
            summary: Option::from("I am the foo".to_string()),
            icon: Option::from(ImageAttributes::SingleUrl(
                "http://example.com/icon".to_string(),
            )),
            image: Option::from(ImageAttributes::SingleUrl(
                "https://example.com/image".to_string(),
            )),
            following: None,
            followers: None,
            liked: None,
            likes: None,
            inbox: None,
            outbox: None,
            public_key: PublicKey {
                id: "https://example.com/foo#key1".to_string(),
                owner: "https://example.com/foo".to_string(),
                public_key_pem: "-----BEGIN PUBLIC KEY----- lslslslssllsslsl".to_string(),
            },
            endpoints: None,
        };
        let j = serde_json::to_string(&a);
        let a2 = serde_json::from_str(&j.unwrap()).unwrap();
        assert_eq!(a, a2)
    }

    #[test]
    fn deserialize_without_optional_attributes() {
        let a = r#"
            {
              "@context": ["https://www.w3.org/ns/activitystreams",
                           {"@language": "ja"}],
              "type": "Person",
              "id": "https://kenzoishii.example.com/",
              "preferredUsername": "kenzoishii",
              "publicKey" : {
                "id": "https://kenzoishii.example.com/foo#key1",
                "owner": "https://kenzoishii.example.com/foo",
                "publicKeyPem": "-----BEGIN PUBLIC KEY----- lcllllll"
              }
            }
        "#;
        let j: Actor = serde_json::from_str(a).unwrap();
        assert_eq!(None, j.name);
        assert_eq!(None, j.summary);
        assert_eq!(None, j.icon);
    }

    #[test]
    fn deserialize_with_icons() {
        let a = r#"
            {
              "@context": ["https://www.w3.org/ns/activitystreams",
                           {"@language": "ja"}],
              "type": "Person",
              "id": "https://kenzoishii.example.com/",
              "preferredUsername": "kenzoishii",
              "icon": "https://example.com/foo.png",
              "publicKey" : {
                "id": "https://kenzoishii.example.com/foo#key1",
                "owner": "https://kenzoishii.example.com/foo",
                "publicKeyPem": "-----BEGIN PUBLIC KEY----- lcllllll"
              }
            }
        "#;
        let j: Actor = serde_json::from_str(a).unwrap();
        assert_eq!(None, j.name);
        assert_eq!(None, j.summary);
        assert_eq!(
            Some(ImageAttributes::SingleUrl(
                "https://example.com/foo.png".to_string()
            )),
            j.icon
        );
    }

    #[test]
    fn roundtrip_pleroma_example_test() {
        let ex = r#"
        {
               "@context" : [
                  "https://www.w3.org/ns/activitystreams",
                  "https://kiwifarms.cc/schemas/litepub-0.1.jsonld",
                  {
                     "@language" : "und"
                  }
               ],
               "alsoKnownAs" : [],
               "attachment" : [],
               "capabilities" : {
                  "acceptsChatMessages" : true
               },
               "discoverable" : false,
               "endpoints" : {
                  "oauthAuthorizationEndpoint" : "https://kiwifarms.cc/oauth/authorize",
                  "oauthRegistrationEndpoint" : "https://kiwifarms.cc/api/v1/apps",
                  "oauthTokenEndpoint" : "https://kiwifarms.cc/oauth/token",
                  "sharedInbox" : "https://kiwifarms.cc/inbox",
                  "uploadMedia" : "https://kiwifarms.cc/api/ap/upload_media"
               },
               "followers" : "https://kiwifarms.cc/users/nxdomain/followers",
               "following" : "https://kiwifarms.cc/users/nxdomain/following",
               "icon" : {
                  "height" : 400,
                  "name" : "Note (400x400)",
                  "type" : "Image",
                  "url" : "https://apb.betabuild.dev/media/remote/2021/212/16-10-6916,kiwifarms.cc-109878132-jpg",
                  "width" : 400
               },
               "id" : "https://kiwifarms.cc/users/nxdomain",
               "image" : {
                  "name" : "Banner Image",
                  "type" : "Image",
                  "url" : "https://apb.betabuild.dev/media/remote/2021/212/16-11-8141,kiwifarms.cc-1491114090-jpg"
               },
               "inbox" : "https://kiwifarms.cc/users/nxdomain/inbox",
               "manuallyApprovesFollowers" : false,
               "name" : "Loyal Subject of the CrunkLord",
               "outbox" : "https://kiwifarms.cc/users/nxdomain/outbox",
               "preferredUsername" : "nxdomain",
               "publicKey" : {
                  "id" : "https://kiwifarms.cc/users/nxdomain#main-key",
                  "owner" : "https://kiwifarms.cc/users/nxdomain",
                  "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw6lTHHUjvw6912osmLIO\nHkaRyQ+wITeXc4FdwLPUn8Zaqhek/VYdFlTbU8mN1SHuoGNoXM9jekAfvlpEEwKZ\nYfZszRPucKKYpFew9Y1TWWaGWZEi78n+inNXMM6djPqS7QZGJmGz+BDWyelnUk+x\nk6ywJSmvy/KEVYxiZH+TON9kMObOWfzclta9opPYJpyoZmxPAbZfwRp61lWiXAHr\nQYbmpTZePTTE3iCbEUt43QoG/+z1DbOJ7orzlviqWrhqApiagwKXvIsxSE3SBtzb\nIl94DBuDa7lR9x+4uaqLc/t5lxwf5NvfeSMBD/7U5Jba8xpEFbDSEwGAlU4HH79t\ntwIDAQAB\n-----END PUBLIC KEY-----\n\n"
               },
               "summary" : "I came here to harsh my mellow.\n<br>\n<br>Not my first rodeo nor my first fedi account. I'm just running from my past.\n<br>\n<br>He/Him/You/Me/Everybody/Everybody",
               "tag" : [],
               "type" : "Person",
               "url" : "https://kiwifarms.cc/users/nxdomain"
            }
        "#;
        let actor: Actor = serde_json::from_str(ex).unwrap();
        let j = serde_json::to_string(&actor).unwrap();
        let _a2: Actor = serde_json::from_str(&j).unwrap();
    }

    #[test]
    fn roundtrip_mastodon_example_test() {
        let ex = r#"
        {
               "@context" : [
                  "https://www.w3.org/ns/activitystreams",
                  "https://w3id.org/security/v1",
                  {
                     "Curve25519Key" : "toot:Curve25519Key",
                     "Device" : "toot:Device",
                     "Ed25519Key" : "toot:Ed25519Key",
                     "Ed25519Signature" : "toot:Ed25519Signature",
                     "EncryptedMessage" : "toot:EncryptedMessage",
                     "IdentityProof" : "toot:IdentityProof",
                     "PropertyValue" : "schema:PropertyValue",
                     "alsoKnownAs" : {
                        "@id" : "as:alsoKnownAs",
                        "@type" : "@id"
                     },
                     "cipherText" : "toot:cipherText",
                     "claim" : {
                        "@id" : "toot:claim",
                        "@type" : "@id"
                     },
                     "deviceId" : "toot:deviceId",
                     "devices" : {
                        "@id" : "toot:devices",
                        "@type" : "@id"
                     },
                     "discoverable" : "toot:discoverable",
                     "featured" : {
                        "@id" : "toot:featured",
                        "@type" : "@id"
                     },
                     "featuredTags" : {
                        "@id" : "toot:featuredTags",
                        "@type" : "@id"
                     },
                     "fingerprintKey" : {
                        "@id" : "toot:fingerprintKey",
                        "@type" : "@id"
                     },
                     "focalPoint" : {
                        "@container" : "@list",
                        "@id" : "toot:focalPoint"
                     },
                     "identityKey" : {
                        "@id" : "toot:identityKey",
                        "@type" : "@id"
                     },
                     "manuallyApprovesFollowers" : "as:manuallyApprovesFollowers",
                     "messageFranking" : "toot:messageFranking",
                     "messageType" : "toot:messageType",
                     "movedTo" : {
                        "@id" : "as:movedTo",
                        "@type" : "@id"
                     },
                     "publicKeyBase64" : "toot:publicKeyBase64",
                     "schema" : "http://schema.org#",
                     "suspended" : "toot:suspended",
                     "toot" : "http://joinmastodon.org/ns#",
                     "value" : "schema:value"
                  }
               ],
               "attachment" : [],
               "devices" : "https://fosstodon.org/users/rcode3/collections/devices",
               "discoverable" : false,
               "endpoints" : {
                  "sharedInbox" : "https://fosstodon.org/inbox"
               },
               "featured" : "https://fosstodon.org/users/rcode3/collections/featured",
               "featuredTags" : "https://fosstodon.org/users/rcode3/collections/tags",
               "followers" : "https://fosstodon.org/users/rcode3/followers",
               "following" : "https://fosstodon.org/users/rcode3/following",
               "icon" : {
                  "mediaType" : "image/png",
                  "type" : "Image",
                  "url" : "https://fosstodon.b-cdn.net/accounts/avatars/000/317/625/original/35b6bcca67d12842.png"
               },
               "id" : "https://fosstodon.org/users/rcode3",
               "image" : {
                  "mediaType" : "image/jpeg",
                  "type" : "Image",
                  "url" : "https://fosstodon.b-cdn.net/accounts/headers/000/317/625/original/21617028d8237f84.jpg"
               },
               "inbox" : "https://fosstodon.org/users/rcode3/inbox",
               "manuallyApprovesFollowers" : false,
               "name" : "RCODE3",
               "outbox" : "https://fosstodon.org/users/rcode3/outbox",
               "preferredUsername" : "rcode3",
               "publicKey" : {
                  "id" : "https://fosstodon.org/users/rcode3#main-key",
                  "owner" : "https://fosstodon.org/users/rcode3",
                  "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxWvsQskS6Y0We0wD6n22\nZLiDive0EyqBFIsgGx/Hp14lEd9FhkY50B5bqF+uqESrvxcp9pycxBFWA3t/dP8P\nC6lIcxLzTl/tIiyHFjXx+BFZ0WiiMKzhLVauaAx63zr3jwTtPKy0/Rfm+MRZ6y0a\nTzF/1PhuAscPRUzwKRFGEN/E7jh8evkMPTtGbXIce5XJkCivJ4Wt3rGZNUwHKo1O\nwvaCzEU6W8IciFO/Bw0h6iGOJJ6r8D0KJ9cIT1pUYTkJgLV9ahPz4u45AeO4tnvP\nR3YdDKM/hiqWmjpJ2m8FYYR3kLpPXshmRtB20ofCirf7dT3/RkY6uTE8pxWmm+oZ\noQIDAQAB\n-----END PUBLIC KEY-----\n"
               },
               "published" : "2021-02-24T00:00:00Z",
               "summary" : "<p>Something clever goes here.</p>",
               "tag" : [],
               "type" : "Person",
               "url" : "https://fosstodon.org/@rcode3"
            }
        "#;
        let actor: Actor = serde_json::from_str(ex).unwrap();
        let j = serde_json::to_string(&actor).unwrap();
        let _a2: Actor = serde_json::from_str(&j).unwrap();
    }
}