Skip to content

nixzhu/Ananda

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Jan 11, 2025
88610d7 · Jan 11, 2025
Jan 11, 2025
Jan 10, 2025
Jan 11, 2025
Jun 21, 2024
Jan 11, 2023
Jul 12, 2024
Jan 11, 2025

Repository files navigation

Ananda

JSON model decoding based on yyjson.

Example

Consider the following JSON:

{
  "profile": {
    "nickname": "NIX",
    "username": "@[email protected]",
    "avatar_url": "https://files.mastodon.social/accounts/avatars/109/329/064/034/222/219/original/371901c6daa01207.png"
  },
  "toots": [
    {
      "id": 1,
      "content": "Hello World!",
      "created_at": "1674127714"
    },
    {
      "id": 2,
      "content": "How do you do?",
      "created_at": "1674127720"
    }
  ]
}

We can create models conforming to the AnandaModel protocol as follows:

import Foundation
import Ananda

struct Mastodon: AnandaModel {
    let profile: Profile
    let toots: [Toot]

    init(json: AnandaJSON) {
        profile = .decode(from: json.profile)
        toots = json.toots.array().map { .decode(from: $0) }
    }
}

extension Mastodon {
    struct Profile: AnandaModel {
        let nickname: String
        let username: String
        let avatarURL: URL

        init(json: AnandaJSON) {
            username = json.username.string()
            nickname = json.nickname.string()
            avatarURL = json.avatar_url.url()
        }
    }
}

extension Mastodon {
    struct Toot: AnandaModel {
        let id: Int
        let content: String
        let createdAt: Date

        init(json: AnandaJSON) {
            id = json.id.int()
            content = json.content.string()
            createdAt = json.created_at.date()
        }
    }
}

To decode a Mastodon instance, use the following code:

let mastodon = Mastodon.decode(from: jsonString)

Or

let mastodon = Mastodon.decode(from: jsonData)

If you only want to decode a specific part of the JSON, such as profile, specify the path as follows:

let profile = Mastodon.Profile.decode(from: jsonData, path: ["profile"])

To decode an array of toots, use the following code:

let toots = [Mastodon.Toot].decode(from: jsonData, path: ["toots"])

Swift Macro

With AnandaMacros, you can use macros to eliminate the need for initialization methods, as shown below:

import Foundation
import Ananda
import AnandaMacros

@AnandaInit
struct Mastodon: AnandaModel {
    let profile: Profile
    let toots: [Toot]
}

extension Mastodon {
    @AnandaInit
    struct Profile: AnandaModel {
        let nickname: String
        let username: String
        @AnandaKey("avatar_url")
        let avatarURL: URL
    }
}

extension Mastodon {
    @AnandaInit
    struct Toot: AnandaModel {
        let id: Int
        let content: String
        @AnandaKey("created_at")
        let createdAt: Date
    }
}

Simple and clean, right?

Benchmark

See AnandaBenchmark.

Tool

You can use Ducky Model Editor to generate AnandaModel from JSON, saving you time.

Ducky Model Editor

Ducky Model Editor