actr-cli 0.3.1

Command line tool for Actor-RTC framework projects
Documentation
use crate::commands::SupportedLanguage;
use crate::commands::codegen::metadata::{ActrGenMetadata, load_metadata};
use crate::commands::codegen::proto_model::ProtoModel;
use crate::commands::codegen::traits::GenContext;
use crate::error::Result;
use std::path::PathBuf;

#[derive(Debug, Clone)]
pub struct ScaffoldCatalog {
    pub local_services: Vec<ScaffoldService>,
    pub remote_services: Vec<ScaffoldService>,
}

#[derive(Debug, Clone)]
pub struct ScaffoldService {
    pub name: String,
    pub package: String,
    pub proto_file: PathBuf,
    pub handler_interface: Option<String>,
    pub workload_type: Option<String>,
    pub dispatcher_type: Option<String>,
    pub client_type: Option<String>,
    pub actr_type: Option<String>,
    pub methods: Vec<ScaffoldMethod>,
}

#[derive(Debug, Clone)]
pub struct ScaffoldMethod {
    pub name: String,
    pub snake_name: String,
    pub input_type: String,
    pub output_type: String,
    pub route_key: String,
}

impl ScaffoldCatalog {
    pub fn load(context: &GenContext, language: SupportedLanguage) -> Result<Self> {
        let expected_language = language_key(language);
        let metadata = load_metadata(&context.output)?
            .filter(|metadata| metadata.language == expected_language)
            .unwrap_or_else(|| ActrGenMetadata::from_proto_model(language, &context.proto_model));
        Ok(Self::from_metadata(&metadata))
    }

    fn from_metadata(metadata: &ActrGenMetadata) -> Self {
        Self {
            local_services: metadata
                .local_services
                .iter()
                .map(|service| ScaffoldService {
                    name: service.name.clone(),
                    package: service.package.clone(),
                    proto_file: PathBuf::from(&service.proto_file),
                    handler_interface: Some(service.handler_interface.clone()),
                    workload_type: Some(service.workload_type.clone()),
                    dispatcher_type: Some(service.dispatcher_type.clone()),
                    client_type: None,
                    actr_type: None,
                    methods: service
                        .methods
                        .iter()
                        .map(|method| ScaffoldMethod {
                            name: method.name.clone(),
                            snake_name: method.snake_name.clone(),
                            input_type: method.input_type.clone(),
                            output_type: method.output_type.clone(),
                            route_key: method.route_key.clone(),
                        })
                        .collect(),
                })
                .collect(),
            remote_services: metadata
                .remote_services
                .iter()
                .map(|service| ScaffoldService {
                    name: service.name.clone(),
                    package: service.package.clone(),
                    proto_file: PathBuf::from(&service.proto_file),
                    handler_interface: None,
                    workload_type: None,
                    dispatcher_type: None,
                    client_type: Some(service.client_type.clone()),
                    actr_type: Some(service.actr_type.clone()),
                    methods: service
                        .methods
                        .iter()
                        .map(|method| ScaffoldMethod {
                            name: method.name.clone(),
                            snake_name: method.snake_name.clone(),
                            input_type: method.input_type.clone(),
                            output_type: method.output_type.clone(),
                            route_key: method.route_key.clone(),
                        })
                        .collect(),
                })
                .collect(),
        }
    }

    pub fn has_any_methods(&self) -> bool {
        self.local_services
            .iter()
            .any(|service| !service.methods.is_empty())
            || self
                .remote_services
                .iter()
                .any(|service| !service.methods.is_empty())
    }
}

fn language_key(language: SupportedLanguage) -> &'static str {
    match language {
        SupportedLanguage::Rust => "rust",
        SupportedLanguage::Python => "python",
        SupportedLanguage::Swift => "swift",
        SupportedLanguage::Kotlin => "kotlin",
        SupportedLanguage::TypeScript => "typescript",
    }
}

#[allow(dead_code)]
fn _proto_model_is_retained_for_generation_ordering(_proto_model: &ProtoModel) {}