awto 0.1.2

Awtomate your 🦀 microservices with awto
Documentation
use std::{
    fmt::{self, Debug},
    str,
};

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum ProtobufType {
    Double,
    Float,
    Int32,
    Int64,
    Uint32,
    Uint64,
    Sint32,
    Sint64,
    Fixed32,
    Fixed64,
    Sfixed32,
    Sfixed64,
    Bool,
    String,
    Bytes,
    Repeated(Box<ProtobufType>),
    Timestamp,
    Custom(ProtobufMessage),
}

pub struct ProtobufTypeFromStrError;

impl str::FromStr for ProtobufType {
    type Err = ProtobufTypeFromStrError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if let Some(inner) = s.strip_prefix("repeated ") {
            return Ok(Self::Repeated(Box::new(inner.parse()?)));
        }
        let protobuf_type = match s {
            "double" => Self::Double,
            "float" => Self::Float,
            "int32" => Self::Int32,
            "int64" => Self::Int64,
            "uint32" => Self::Uint32,
            "uint64" => Self::Uint64,
            "sint32" => Self::Sint32,
            "sint64" => Self::Sint64,
            "fixed32" => Self::Fixed32,
            "fixed64" => Self::Fixed64,
            "sfixed32" => Self::Sfixed32,
            "sfixed64" => Self::Sfixed64,
            "bool" => Self::Bool,
            "String" => Self::String,
            "bytes" => Self::Bytes,
            "google.protobuf.Timestamp" => Self::Timestamp,
            _ => return Err(ProtobufTypeFromStrError),
        };
        Ok(protobuf_type)
    }
}

impl fmt::Display for ProtobufType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Double => write!(f, "double"),
            Self::Float => write!(f, "float"),
            Self::Int32 => write!(f, "int32"),
            Self::Int64 => write!(f, "int64"),
            Self::Uint32 => write!(f, "uint32"),
            Self::Uint64 => write!(f, "uint64"),
            Self::Sint32 => write!(f, "sint32"),
            Self::Sint64 => write!(f, "sint64"),
            Self::Fixed32 => write!(f, "fixed32"),
            Self::Fixed64 => write!(f, "fixed64"),
            Self::Sfixed32 => write!(f, "sfixed32"),
            Self::Sfixed64 => write!(f, "sfixed64"),
            Self::Bool => write!(f, "bool"),
            Self::String => write!(f, "string"),
            Self::Bytes => write!(f, "bytes"),
            Self::Repeated(inner) => write!(f, "repeated {}", inner),
            Self::Timestamp => write!(f, "google.protobuf.Timestamp"),
            Self::Custom(inner) => write!(f, "{}", inner.name),
        }
    }
}

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct ProtobufField {
    pub name: String,
    pub ty: ProtobufType,
    pub required: bool,
}

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct ProtobufMethod {
    pub is_async: bool,
    pub name: String,
    pub param: ProtobufMessage,
    pub returns: ProtobufMessage,
    pub returns_result: bool,
}

pub trait IntoProtobufService {
    fn protobuf_service() -> ProtobufService;
}

pub trait IntoProtobufMessage {
    fn protobuf_message() -> ProtobufMessage;
}

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct ProtobufSchema {
    pub name: String,
    pub fields: Vec<ProtobufField>,
    pub generated_code: Option<String>,
}

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct ProtobufMessage {
    pub name: String,
    pub fields: Vec<ProtobufField>,
}

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct ProtobufService {
    pub methods: Vec<ProtobufMethod>,
    pub module_path: String,
    pub name: String,
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::prelude::*;
    use crate::tests_cfg::*;

    #[test]
    fn message_name() {
        assert_eq!(Product::protobuf_message().name, "Product");
    }

    #[test]
    fn columns() {
        let fields = Product::protobuf_message().fields;

        let expected = vec![
            ProtobufField {
                name: "id".to_string(),
                ty: ProtobufType::String,
                required: true,
            },
            ProtobufField {
                name: "created_at".to_string(),
                ty: ProtobufType::Timestamp,
                required: true,
            },
            ProtobufField {
                name: "updated_at".to_string(),
                ty: ProtobufType::Timestamp,
                required: true,
            },
            ProtobufField {
                name: "name".to_string(),
                ty: ProtobufType::String,
                required: true,
            },
            ProtobufField {
                name: "price".to_string(),
                ty: ProtobufType::Int64,
                required: true,
            },
            ProtobufField {
                name: "description".to_string(),
                ty: ProtobufType::String,
                required: false,
            },
        ];
        assert_eq!(fields, expected);
    }
}