geam-core 0.2.1

Typed Gleam planning, host, and execution core for Geam
Documentation
pub use crate::host::{
    HostCall, HostCallCompletion, HostCallError, HostCallable, HostComponentProfile,
    HostConstruction, HostConstructions, HostCustom, HostCustomConstructorAt,
    HostCustomConstructorDefinition, HostCustomConstructorList, HostCustomConstructorListEnd,
    HostCustomField, HostCustomFieldList, HostCustomFieldListEnd, HostCustomIndex0,
    HostCustomIndexNext, HostCustomSchema, HostCustomType, HostExternal, HostExternalBinding,
    HostExternalEquality, HostExternalHashing, HostExternalInspection, HostExternalSchema,
    HostExternalStorage, HostExternalStore, HostExternalType, HostFunctionType, HostList,
    HostListType, HostProfile, HostProvider, HostProviderComponent,
    HostProviderComponentInitialization, HostProviderComponentRegistration,
    HostProviderConfiguration, HostProviderInitializationError, HostProviderModule,
    HostRegistrationError, HostStoredType, HostStoredValue, HostTuple, HostTupleType, HostType,
    HostTypeAt, HostTypeIndex0, HostTypeIndexNext, HostTypeList, HostTypeListEnd,
    HostTypeParameter, HostTypeSequence,
};
pub use crate::provider::ExternalPayload;
pub use crate::provider::advanced::{
    Equality, Hashing, Index0, Inspection, Next, ProviderDynamicInput, ProviderDynamicValue,
    Retained, RetainedExternalPayload,
};
pub use crate::provider::{
    Call, Callback, HostResult, List, MissingCallbackContext, MissingExternalInputContext,
    MissingExternalOutputContext, MissingStoredContext, MissingValueContext, ProviderActiveCall,
    ProviderCallPlaceholder, ProviderExternalInputContext, ProviderExternalItem,
    ProviderExternalListDecoder, ProviderExternalOutput, ProviderExternalPayloadAccess,
    ProviderInputListContext, ProviderListContext, ProviderListCustomFields,
    ProviderListItemDecoder, ProviderListItemValue, ProviderScalarListDecoder, ProviderSharedCall,
    ProviderStoredInput, ProviderStoredOutput, ProviderStoredOwner, ProviderValueContext, Stored,
    Value,
};
pub use crate::provider::{
    ProviderCallbackCodec, ProviderCallbackContext, ProviderConstruction,
    ProviderConstructionIndex0, ProviderConstructionIndexNext, ProviderConstructionList,
    ProviderConstructionRequirementAt, ProviderConstructionRequirements, ProviderConstructions,
    ProviderError, ProviderExternalCodec, ProviderExternalDeclaration, ProviderInputValue,
    ProviderListInputCodec, ProviderListInputValue, ProviderNoConstructions, ProviderNone,
    ProviderOk, ProviderOption, ProviderOutputValue, ProviderResult, ProviderRootOutputValue,
    ProviderSome, ProviderValue,
};
pub use crate::provider::{retain_argument, retain_dynamic};
pub use crate::provider_support::HostOpaqueFunctionType;
pub use ecow::EcoString;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};

/// Package identity shared by provider and module macro expansions.
pub trait ProviderPackage: HostProviderComponent {
    const PACKAGE: &'static str;
}

/// Static registration protocol generated by one provider module.
#[doc(hidden)]
pub trait ProviderModuleRegistration<Profile>
where
    Profile: HostProfile,
{
    fn module() -> Result<HostProviderModule<Profile>, HostRegistrationError>;
}

/// Static declaration identity shared by generated custom codecs.
#[doc(hidden)]
pub trait ProviderCustomDeclaration {
    type Schema: crate::HostCustomSchema;
    type Input;
}

/// Directional input declaration generated for one ordinary custom type.
#[doc(hidden)]
pub trait ProviderCustomInputDeclaration {
    type Schema: crate::HostCustomSchema;
    type Output;
}

/// Marker used when a custom declaration is intentionally output-only.
#[doc(hidden)]
pub struct NoCustomInput;

pub fn component_initialization_error<Component>(
    error: crate::provider::InitializationError,
) -> crate::HostProviderInitializationError
where
    Component: HostProviderComponent,
{
    crate::HostProviderInitializationError::for_component::<Component>(error.reason())
}

/// Hashes an ordinary Rust payload for generated external source semantics.
#[doc(hidden)]
pub fn external_payload_hash<Payload>(payload: &Payload) -> u64
where
    Payload: Hash + ?Sized,
{
    let mut hasher = DefaultHasher::new();
    payload.hash(&mut hasher);
    hasher.finish()
}

#[cfg(test)]
mod tests {
    use super::{
        HostProviderComponent, ProviderPackage, component_initialization_error,
        external_payload_hash,
    };
    use crate::provider::InitializationError;
    use std::collections::hash_map::DefaultHasher;
    use std::hash::{Hash, Hasher};

    struct Component;

    impl HostProviderComponent for Component {
        const ID: &'static str = "macro-support";
        type Stores = ();
        type RunState = ();
    }

    impl ProviderPackage for Component {
        const PACKAGE: &'static str = "macro_support";
    }

    #[test]
    fn initialization_support_adds_the_static_component_identity() {
        let error = component_initialization_error::<Component>(InitializationError::new(
            "configuration is incomplete",
        ));

        assert_eq!(error.component_id(), "macro-support");
        assert_eq!(error.reason(), "configuration is incomplete");
        assert_eq!(Component::PACKAGE, "macro_support");
    }

    #[test]
    fn external_payload_hash_uses_ordinary_rust_hashing() {
        let value = ("tag", 7u64);
        let equal = ("tag", 7u64);
        let mut expected = DefaultHasher::new();
        value.hash(&mut expected);

        assert_eq!(external_payload_hash(&value), expected.finish());
        assert_eq!(external_payload_hash(&value), external_payload_hash(&equal));
    }
}