aquadoggo 0.4.0

Embeddable p2p network node
Documentation
// SPDX-License-Identifier: AGPL-3.0-or-later

use async_graphql::indexmap::IndexMap;
use p2panda_rs::schema::Schema;

use crate::graphql::client::dynamic_types::utils::{graphql_typename, metafield, metaobject};

/// Returns the GraphQL type name of the document fields object for a given schema.
pub fn type_name(schema: &Schema) -> String {
    format!("{}Fields", schema.id())
}

/// Represents fields for documents of a specific schema in the GraphQL client API.
pub struct DocumentFields(&'static Schema);

impl DocumentFields {
    /// Get a new instance for the given schema, which must be `static`.
    pub fn new(schema: &'static Schema) -> Self {
        Self(schema)
    }

    /// Returns the type name, formatted like `<SchemaId>Fields`.
    pub fn type_name(&self) -> String {
        type_name(self.0)
    }

    /// Generate an object type and register it in a GraphQL schema registry.
    pub fn register_type(&self, registry: &mut async_graphql::registry::Registry) {
        let mut fields = IndexMap::new();

        // Create a GraphQL field for every schema field.
        self.0.fields().iter().for_each(|(field_name, field_type)| {
            fields.insert(
                field_name.to_string(),
                metafield(field_name, None, &graphql_typename(field_type)),
            );
        });

        // Create a meta object with the fields defined above and insert it into the registry.
        registry.types.insert(
            self.type_name(),
            metaobject(
                &self.type_name(),
                Some("Data fields available on documents of this schema."),
                fields,
            ),
        );
    }
}