mercur 0.1.5

mercur - junolang package manager
use flatbuffers::{FlatBufferBuilder, WIPOffset};

use crate::registry::compile::{
    hash::{authority_id, namespace_id},
    parse::{
        AuthorityDefinition as AuthorityTomlDefinition,
        RegistryDefinition as RegistryTomlDefinition,
        RegistryHistoryDefinition as RegistryHistoryTomlDefinition,
    },
    version::parse_date,
};

use crate::registry::schema::registry::{
    AuthorityDefinition, AuthorityDefinitionArgs, RegistryDefinition, RegistryDefinitionArgs,
    RegistryHistoryDefinition, RegistryHistoryDefinitionArgs, RegistryRefType,
};

use xxhash_rust::xxh3::xxh3_64;

pub fn compile_authority<'a>(
    builder: &mut FlatBufferBuilder<'a>,
    authority: &AuthorityTomlDefinition,
) -> WIPOffset<AuthorityDefinition<'a>> {
    let id = builder.create_string(&authority.metadata.id);

    let signing_keys = authority
        .metadata
        .signing_keys
        .iter()
        .map(|k| builder.create_string(k))
        .collect::<Vec<_>>();

    let signing_keys = builder.create_vector(&signing_keys);

    let registries = authority
        .registries
        .iter()
        .map(|r| compile_registry_definition(builder, r))
        .collect::<Vec<_>>();

    let registries = builder.create_vector(&registries);

    let authority_id = xxh3_64(authority.metadata.id.as_bytes());

    AuthorityDefinition::create(
        builder,
        &AuthorityDefinitionArgs {
            id: Some(id),
            authority_id,
            registries: Some(registries),
            signing_keys: Some(signing_keys),
        },
    )
}

fn compile_registry_definition<'a>(
    builder: &mut FlatBufferBuilder<'a>,
    registry: &RegistryTomlDefinition,
) -> WIPOffset<RegistryDefinition<'a>> {
    let reference = builder.create_string(&registry.reference);

    let namespace = builder.create_string(&registry.namespace);

    let history = registry
        .history
        .iter()
        .map(|h| compile_registry_history(builder, h))
        .collect::<Vec<_>>();

    let history = builder.create_vector(&history);

    let namespace_id = xxh3_64(registry.namespace.as_bytes());

    RegistryDefinition::create(
        builder,
        &RegistryDefinitionArgs {
            type_: parse_registry_ref_type(&registry.registry_type),

            ref_: Some(reference),

            namespace: Some(namespace),

            namespace_id,

            history: Some(history),
        },
    )
}

fn compile_registry_history<'a>(
    builder: &mut FlatBufferBuilder<'a>,
    history: &RegistryHistoryTomlDefinition,
) -> WIPOffset<RegistryHistoryDefinition<'a>> {
    let reference = builder.create_string(&history.reference);

    RegistryHistoryDefinition::create(
        builder,
        &RegistryHistoryDefinitionArgs {
            type_: parse_registry_ref_type(&history.registry_type),

            ref_: Some(reference),

            deprecated: history.deprecated,

            until: parse_date(&history.until),
        },
    )
}

fn parse_registry_ref_type(ty: &str) -> RegistryRefType {
    match ty.to_ascii_lowercase().as_str() {
        "github" => RegistryRefType::Github,

        "http" => RegistryRefType::HTTP,

        "inregistry" => RegistryRefType::InRegistry,

        _ => RegistryRefType::NoRef,
    }
}