lenso-capability-organization-admin 0.2.0

Generated Organization Admin Capability contracts for Lenso vNext.
Documentation
// @generated by lenso-contract-codegen; do not edit.
use std::{fmt, rc::Rc};
use futures::future::LocalBoxFuture;
use lenso_kernel::{InvocationContext, NativeRequestEndpoint, NativeRequestFuture, NativeRequestHandle, PluginDependencies, RequestCapability, RuntimeFailure};

use lenso_plugin_authoring::{BoundCapabilityClient, CapabilityClient, CapabilityClientMany};
pub const CAPABILITY_ID: &str = "lenso.organization-admin@2";
pub const DESCRIPTOR_VERSION: &str = "1.0.0";
pub const PORTABLE: bool = true;
pub const CROSS_LANE_TRANSFER: bool = true;
pub const ORGANIZATION_ADMIN_CAPABILITY_ID: &str = CAPABILITY_ID;
pub const ORGANIZATION_ADMIN_DESCRIPTOR_VERSION: &str = DESCRIPTOR_VERSION;

#[doc(hidden)]
#[macro_export]
macro_rules! __lenso_provided_organization_admin { () => { "{\"capability_id\":\"lenso.organization-admin@2\",\"descriptor_version\":\"1.0.0\",\"operations\":[\"create_organization\"],\"operation_kinds\":{},\"default_admission\":{\"queue_capacity\":0,\"max_concurrency\":1},\"operation_admissions\":{},\"event_admission\":null,\"cross_lane_transfer\":true}" }; }

#[doc(hidden)]
#[macro_export]
macro_rules! __lenso_required_organization_admin_client { () => { "{\"capability_id\":\"lenso.organization-admin@2\",\"descriptor_version\":\"1.0.0\",\"cardinality\":\"one\"}" }; }

#[doc(hidden)]
#[macro_export]
macro_rules! __lenso_required_many_organization_admin_client { () => { "{\"capability_id\":\"lenso.organization-admin@2\",\"descriptor_version\":\"1.0.0\",\"cardinality\":\"many\"}" }; }

pub const CREATE_ORGANIZATION_OPERATION: &str = "create_organization";

pub use lenso_contract_runtime::{UnknownDomainError};
use lenso_contract_runtime::{decode_portable_json, encode_portable_json};

#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct CreateOrganizationRequest {
    #[serde(rename = "idempotency_key")]
    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
    pub idempotency_key: String,
    #[serde(rename = "name")]
    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
    pub name: String,
    #[serde(rename = "owner_subject")]
    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
    pub owner_subject: String,
    #[serde(rename = "slug")]
    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
    pub slug: String,
}

#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct CreateOrganizationResponse {
    #[serde(rename = "created")]
    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
    pub created: bool,
    #[serde(rename = "organization_id")]
    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
    pub organization_id: String,
    #[serde(rename = "owner_membership_id")]
    #[serde(deserialize_with = "lenso_contract_runtime::serde::deserialize_required")]
    pub owner_membership_id: String,
}

#[derive(Clone, Debug, PartialEq)]
pub enum CreateOrganizationError {
    Forbidden,
    IdempotencyConflict,
    InvalidOrganization,
    SlugConflict,
    Unknown(UnknownDomainError),
}

#[derive(Debug)]
pub struct OrganizationAdmin;
impl RequestCapability for OrganizationAdmin {
    type Request = CreateOrganizationRequest;
    type Response = CreateOrganizationResponse;
    type DomainError = CreateOrganizationError;
    const ID: &'static str = CAPABILITY_ID;
    const DESCRIPTOR_VERSION: &'static str = DESCRIPTOR_VERSION;

    fn invoke_native(endpoint: &dyn NativeRequestEndpoint, operation: &str, request: Self::Request, context: InvocationContext) -> NativeRequestFuture<Self> {
        if operation != CREATE_ORGANIZATION_OPERATION {
            return lenso_kernel::invoke_typed_or_erased_native_request::<Self>(endpoint, operation, request, context);
        }
        let Some(typed_endpoint) = endpoint
            .typed_endpoint()
            .and_then(|endpoint| endpoint.downcast_ref::<OrganizationAdminRequestEndpoint>())
        else {
            return lenso_kernel::invoke_typed_or_erased_native_request::<Self>(endpoint, operation, request, context);
        };
        Rc::clone(&typed_endpoint.provider).create_organization(context, request)
    }
}

impl serde::Serialize for CreateOrganizationError {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        use serde::ser::SerializeMap;
        match self {
            Self::Forbidden => serializer.serialize_str("forbidden"),
            Self::IdempotencyConflict => serializer.serialize_str("idempotency_conflict"),
            Self::InvalidOrganization => serializer.serialize_str("invalid_organization"),
            Self::SlugConflict => serializer.serialize_str("slug_conflict"),
            Self::Unknown(value) => {
                let mut map = serializer.serialize_map(Some(1 + usize::from(value.payload.is_some()) + value.extra.len()))?;
                map.serialize_entry("code", &value.code)?;
                if let Some(payload) = &value.payload {
                    map.serialize_entry("payload", payload)?;
                }
                for (key, extra) in &value.extra {
                    map.serialize_entry(key, extra)?;
                }
                map.end()
            },
        }
    }
}

impl<'de> serde::Deserialize<'de> for CreateOrganizationError {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let value = <serde_json::Value as serde::Deserialize>::deserialize(deserializer)?;
        match value {
            serde_json::Value::String(code) => match code.as_str() {
                "forbidden" => Ok(Self::Forbidden),
                "idempotency_conflict" => Ok(Self::IdempotencyConflict),
                "invalid_organization" => Ok(Self::InvalidOrganization),
                "slug_conflict" => Ok(Self::SlugConflict),
                _ => Ok(Self::Unknown(UnknownDomainError { code, payload: None, extra: std::collections::BTreeMap::new() })),
            },
            serde_json::Value::Object(mut object) => {
                let Some(code) = object.remove("code").and_then(|value| value.as_str().map(ToOwned::to_owned)) else {
                    return Err(serde::de::Error::custom("Domain Error object is missing a string code"));
                };
                let payload = object.remove("payload");
                let extra = object.into_iter().collect::<std::collections::BTreeMap<_, _>>();
                Ok(Self::Unknown(UnknownDomainError { code, payload, extra }))
            }
            other => Err(serde::de::Error::custom(format!("Domain Error must be a string or object, got {other}"))),
        }
    }
}

pub fn encode_create_organization_request(value: &CreateOrganizationRequest) -> Result<String, serde_json::Error> { encode_portable_json(value) }
pub fn decode_create_organization_request(wire: &str) -> Result<CreateOrganizationRequest, serde_json::Error> { decode_portable_json(wire) }
pub fn encode_create_organization_response(value: &CreateOrganizationResponse) -> Result<String, serde_json::Error> { encode_portable_json(value) }
pub fn decode_create_organization_response(wire: &str) -> Result<CreateOrganizationResponse, serde_json::Error> { decode_portable_json(wire) }
pub fn encode_create_organization_error(value: &CreateOrganizationError) -> Result<String, serde_json::Error> { encode_portable_json(value) }
pub fn decode_create_organization_error(wire: &str) -> Result<CreateOrganizationError, serde_json::Error> { decode_portable_json(wire) }

#[doc(hidden)]
pub trait __LensoIntoOrganizationAdminCreateOrganizationResult {
    fn __lenso_into_result(self) -> Result<Result<CreateOrganizationResponse, CreateOrganizationError>, RuntimeFailure>;
}
impl __LensoIntoOrganizationAdminCreateOrganizationResult for Result<CreateOrganizationResponse, CreateOrganizationError> {
    fn __lenso_into_result(self) -> Result<Result<CreateOrganizationResponse, CreateOrganizationError>, RuntimeFailure> { Ok(self) }
}
impl __LensoIntoOrganizationAdminCreateOrganizationResult for Result<Result<CreateOrganizationResponse, CreateOrganizationError>, RuntimeFailure> {
    fn __lenso_into_result(self) -> Result<Result<CreateOrganizationResponse, CreateOrganizationError>, RuntimeFailure> { self }
}
impl __LensoIntoOrganizationAdminCreateOrganizationResult for Result<CreateOrganizationResponse, lenso_plugin_authoring::PluginError<CreateOrganizationError, RuntimeFailure>> {
    fn __lenso_into_result(self) -> Result<Result<CreateOrganizationResponse, CreateOrganizationError>, RuntimeFailure> {
        match self {
            Ok(value) => Ok(Ok(value)),
            Err(lenso_plugin_authoring::PluginError::Domain(error)) => Ok(Err(error)),
            Err(lenso_plugin_authoring::PluginError::Runtime(error)) => Err(error),
        }
    }
}
impl __LensoIntoOrganizationAdminCreateOrganizationResult for Result<CreateOrganizationResponse, OrganizationAdminInvocationError> {
    fn __lenso_into_result(self) -> Result<Result<CreateOrganizationResponse, CreateOrganizationError>, RuntimeFailure> {
        match self {
            Ok(value) => Ok(Ok(value)),
            Err(OrganizationAdminInvocationError::Domain(error)) => Ok(Err(error)),
            Err(OrganizationAdminInvocationError::Runtime(error)) => Err(error),
        }
    }
}

pub trait OrganizationAdminProvider: fmt::Debug + 'static {
    fn create_organization(&self, context: InvocationContext, request: CreateOrganizationRequest) -> NativeRequestFuture<OrganizationAdmin>;
}

#[doc(hidden)]
#[macro_export]
macro_rules! __lenso_native_lower_organization_admin {
    ($plugin:ty, $support:path) => {
        use $support as __LensoNativeSupportOrganizationAdmin;
        impl $crate::OrganizationAdminProvider for $plugin {
        fn create_organization(&self, context: __LensoNativeSupportOrganizationAdmin::InvocationContext, request: $crate::CreateOrganizationRequest) -> __LensoNativeSupportOrganizationAdmin::NativeRequestFuture<$crate::OrganizationAdmin> {
            let plugin = self.clone();
            ::std::boxed::Box::pin(async move {
                let result = <$plugin>::create_organization(&plugin, context, request).await;
                $crate::__LensoIntoOrganizationAdminCreateOrganizationResult::__lenso_into_result(result)
            })
        }
        }
    };
}

#[derive(Debug)]
struct OrganizationAdminRequestEndpoint { provider: Rc<dyn OrganizationAdminProvider> }

#[derive(Debug)]
pub struct OrganizationAdminEndpoint<P: OrganizationAdminProvider> { provider: Rc<P>, request_endpoint: OrganizationAdminRequestEndpoint }
impl<P: OrganizationAdminProvider> OrganizationAdminEndpoint<P> {
    pub fn new(provider: P) -> Self {
        let provider = Rc::new(provider);
        let request_provider: Rc<dyn OrganizationAdminProvider> = provider.clone();
        Self { provider, request_endpoint: OrganizationAdminRequestEndpoint { provider: request_provider } }
    }
}

impl<P: OrganizationAdminProvider> NativeRequestEndpoint for OrganizationAdminEndpoint<P> {
    fn capability_id(&self) -> &'static str { CAPABILITY_ID }
    fn descriptor_version(&self) -> &'static str { DESCRIPTOR_VERSION }
    fn operations(&self) -> &'static [&'static str] { &[
        CREATE_ORGANIZATION_OPERATION,
    ] }
    fn typed_endpoint(&self) -> Option<&dyn std::any::Any> { Some(&self.request_endpoint) }
    fn invoke(&self, operation: &str, request: Box<dyn std::any::Any>, context: InvocationContext) -> LocalBoxFuture<'static, Result<Result<Box<dyn std::any::Any>, Box<dyn std::any::Any>>, RuntimeFailure>> {
        match operation {
            CREATE_ORGANIZATION_OPERATION => {
                let Ok(request) = request.downcast::<CreateOrganizationRequest>() else {
                    return Box::pin(futures::future::ready(Err(RuntimeFailure::ProtocolViolation { capability: CAPABILITY_ID })));
                };
                let invocation = Rc::clone(&self.provider).create_organization(context, *request);
                Box::pin(async move {
                    invocation.await.map(|result| {
                        result
                            .map(|value| Box::new(value) as Box<dyn std::any::Any>)
                            .map_err(|error| Box::new(error) as Box<dyn std::any::Any>)
                    })
                })
            }
            _ => Box::pin(futures::future::ready(Err(RuntimeFailure::UnknownOperation { capability: CAPABILITY_ID, operation: operation.to_owned() }))),
        }
    }
}

#[doc(hidden)]
#[macro_export]
macro_rules! __lenso_native_endpoints_organization_admin {
    ($provider:expr, $support:path) => {{
        use $support as __LensoNativeSupport;
        let endpoint = ::std::rc::Rc::new($crate::OrganizationAdminEndpoint::new($provider));
        (
            vec![endpoint.clone() as ::std::rc::Rc<dyn __LensoNativeSupport::NativeRequestEndpoint>],
            vec![],
            vec![],
        )
    }};
}

#[doc(hidden)]
#[macro_export]
macro_rules! __lenso_native_provide_organization_admin {
    ($provider:expr, $lifecycle:expr, $support:path) => {{
        use $support as __LensoNativeSupport;
        let (request_endpoints, stream_endpoints, event_endpoints) =
            $crate::__lenso_native_endpoints_organization_admin!($provider, $support);
        __LensoNativeSupport::NativePluginInstance::with_all_endpoints(
            request_endpoints,
            stream_endpoints,
            event_endpoints,
            $lifecycle,
        )
    }};
}

#[derive(Debug)]
pub struct OrganizationAdminClient {
    create_organization: NativeRequestHandle<OrganizationAdmin>,
}
impl OrganizationAdminClient {
    pub fn new(handle: NativeRequestHandle<OrganizationAdmin>) -> Self {
        Self { create_organization: handle }
    }

    pub fn from_dependencies(dependencies: &PluginDependencies) -> Result<Self, RuntimeFailure> {
        <Self as CapabilityClient>::from_dependencies(dependencies)
    }

    pub async fn create_organization(&self, request: CreateOrganizationRequest) -> Result<CreateOrganizationResponse, OrganizationAdminInvocationError> {
        self.create_organization.invoke(CREATE_ORGANIZATION_OPERATION, request).await
            .map_err(OrganizationAdminInvocationError::Runtime)?
            .map_err(OrganizationAdminInvocationError::Domain)
    }

    pub async fn create_organization_with_context(&self, context: InvocationContext, request: CreateOrganizationRequest) -> Result<CreateOrganizationResponse, OrganizationAdminInvocationError> {
        self.create_organization.invoke_with_context(CREATE_ORGANIZATION_OPERATION, context, request).await
            .map_err(OrganizationAdminInvocationError::Runtime)?
            .map_err(OrganizationAdminInvocationError::Domain)
    }
}

impl CapabilityClient for OrganizationAdminClient {
    type Dependencies = PluginDependencies;
    type Error = RuntimeFailure;

    const CAPABILITY_ID: &'static str = CAPABILITY_ID;
    const DESCRIPTOR_VERSION: &'static str = DESCRIPTOR_VERSION;

    fn from_dependencies(dependencies: &PluginDependencies) -> Result<Self, RuntimeFailure> {
        Ok(Self {
            create_organization: dependencies.one::<OrganizationAdmin>()?,
        })
    }

    fn already_connected() -> RuntimeFailure {
        RuntimeFailure::PluginFailure {
            detail: format!("Capability Port {CAPABILITY_ID} was connected more than once"),
        }
    }
}

impl CapabilityClientMany for OrganizationAdminClient {
    fn many_from_dependencies(
        dependencies: &PluginDependencies,
    ) -> Result<Vec<BoundCapabilityClient<Self>>, RuntimeFailure> {
        dependencies
            .bindings()
            .iter()
            .filter(|binding| binding.capability_id() == CAPABILITY_ID)
            .map(|binding| {
                Ok(BoundCapabilityClient::new(
                    binding.provider_instance(),
                    Self {
                    create_organization: binding.handle().ok_or(RuntimeFailure::Unavailable { capability: CAPABILITY_ID })?.typed::<OrganizationAdmin>()?,
                    },
                ))
            })
            .collect()
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum OrganizationAdminInvocationError {
    Domain(CreateOrganizationError),
    Runtime(RuntimeFailure),
}