spatialos-codegen 0.2.1

Codegen tool used with spatialos-macro and spatialos-sdk
Documentation
pub mod ast_node;
pub mod root;
pub mod schema_file;

use std::convert::identity;

pub use ast_node::ASTNode;
pub use root::{ASTBuilder, AST};
pub use schema_file::SchemaFile;

#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Command {
    pub name: String,
    pub r_type: DataType,
    pub args: Vec<DataType>,
}

#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Event {
    pub name: String,
    pub r_type: DataType,
}

#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Component {
    pub name: String,
    pub id: u32,
    pub members: Vec<Member>,
    pub events: Vec<Event>,
    pub commands: Vec<Command>,
    pub comments: Vec<String>,
    pub enums: Vec<Enum>,
    pub types: Vec<Type>,
}

impl Component {
    pub fn get_export(&self) -> Option<String> {
        Some(self.name.clone())
    }

    pub fn get_exports(data: &[Self]) -> Vec<String> {
        data.iter()
            .map(Self::get_export)
            .filter_map(identity)
            .collect()
    }
}

#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Member {
    pub name: String,
    pub m_type: DataType,
    pub id: u32,
    pub comments: Vec<String>,
}

#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Variant {
    pub name: String,
    pub id: u32,
    pub comments: Vec<String>,
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Type {
    pub name: String,
    pub members: Vec<Member>,
    pub comments: Vec<String>,
    pub types: Vec<Type>,
    pub enums: Vec<Enum>,
}

impl Type {
    pub fn get_export(&self) -> Option<String> {
        Some(self.name.clone())
    }

    pub fn get_exports(data: &[Self]) -> Vec<String> {
        data.iter()
            .map(Self::get_export)
            .filter_map(identity)
            .collect()
    }
}
#[derive(Debug, Eq, PartialEq)]
pub struct PackageNode {
    pub name: String,
    pub inner: Vec<ASTNode>,
}

impl PackageNode {
    pub fn add_node(self, node: ASTNode) -> Self {
        let mut inner = self.inner;
        inner.push(node);
        Self {
            name: self.name,
            inner,
        }
    }

    pub fn has_path<S: AsRef<str>>(&self, path: S) -> bool {
        self.inner
            .iter()
            .map(|node| match &node {
                ASTNode::SchemaNode(_) => false,
                ASTNode::PackageNode(pn) => pn.name == *path.as_ref(),
            })
            .fold(false, |acc, val| acc | val)
    }

    pub fn get_exports(&self) -> Vec<String> {
        vec![self.name.clone()]
    }
}

#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Enum {
    pub name: String,
    pub variants: Vec<Variant>,
    pub comments: Vec<String>,
}

impl Enum {
    pub fn get_export(&self) -> Option<String> {
        Some(self.name.clone())
    }

    pub fn get_exports(data: &[Self]) -> Vec<String> {
        data.iter()
            .map(Self::get_export)
            .filter_map(identity)
            .collect()
    }
}

#[derive(Debug, Eq, PartialEq, Clone)]
pub enum DataType {
    Bool,
    Uint32,
    Uint64,
    Int32,
    Int64,
    SInt32,
    SInt64,
    Fixed32,
    Fixed64,
    SFixed32,
    SFixed64,
    Float,
    Double,
    String,
    Bytes,
    EntityID,
    Entity,
    Map(Box<DataType>, Box<DataType>),
    List(Box<DataType>),
    Option(Box<DataType>),
    UserDefined(UserDefinedType),
}

impl DataType {
    pub fn spatial_type(&self) -> String {
        match self {
            Self::Bool => "bool".to_string(),
            Self::Float => "float".to_string(),
            Self::Bytes => "bytes".to_string(),
            Self::Int32 => "int32".to_string(),
            Self::Int64 => "int64".to_string(),
            Self::String => "string".to_string(),
            Self::Double => "double".to_string(),
            Self::Uint32 => "uint32".to_string(),
            Self::Uint64 => "uint64".to_string(),
            Self::SInt32 => "sint32".to_string(),
            Self::SInt64 => "sint64".to_string(),
            Self::Fixed32 => "fixed32".to_string(),
            Self::Fixed64 => "fixed64".to_string(),
            Self::SFixed32 => "sfixed32".to_string(),
            Self::SFixed64 => "sfixed64".to_string(),
            Self::EntityID => "EntityId".to_string(),
            Self::Entity => "Entity".to_string(),
            Self::Map(fst, snd) => format!("map<{},{}>", fst.spatial_type(), snd.spatial_type()),
            Self::List(fst) => format!("list<{}>", fst.spatial_type()),
            Self::Option(fst) => format!("option<{}>", fst.spatial_type()),
            Self::UserDefined(fst) => fst.spatial_type(),
        }
    }

    pub fn rust_type(&self) -> String {
        match self {
            Self::Bool => "bool".to_string(),
            Self::Uint32 => "u32".to_string(),
            Self::Uint64 => "u64".to_string(),
            Self::Int32 => "i32".to_string(),
            Self::Int64 => "i64".to_string(),
            Self::Float => "f32".to_string(),
            Self::Double => "f64".to_string(),
            Self::String => "String".to_string(),
            Self::Bytes => "Vec<u8>".to_string(),
            Self::Map(fst, snd) => {
                format!("HashMap<{}, {}>", (*fst).rust_type(), (*snd).rust_type())
            }
            Self::List(fst) => format!("Vec<{}>", (*fst).rust_type()),
            Self::Option(fst) => format!("Option<{}>", (*fst).rust_type()),
            Self::UserDefined(fst) => fst.rust_type(),
            _ => "uninmplemented()!".to_string(),
        }
    }
}

#[derive(Debug, Eq, PartialEq, Clone)]
pub enum ResolvedTypeKind {
    Enum,
    Type,
    Component,
}

#[derive(Debug, Eq, PartialEq, Clone)]
pub enum UserDefinedType {
    Unresolved(String),
    Resolved(String, ResolvedTypeKind),
}

impl From<&(String, ResolvedTypeKind)> for UserDefinedType {
    fn from(data: &(String, ResolvedTypeKind)) -> Self {
        Self::Resolved(data.0.clone(), data.1.clone())
    }
}

impl UserDefinedType {
    pub fn spatial_type(&self) -> String {
        match self {
            Self::Unresolved(name) => panic!("{} is not resolved in the current schema", name),
            Self::Resolved(name, kind) => match kind {
                ResolvedTypeKind::Enum => "enum",
                ResolvedTypeKind::Type => "type",
                ResolvedTypeKind::Component => panic!("You can't reference component {}", name),
            }
            .to_string(),
        }
    }

    pub fn rust_type(&self) -> String {
        match self {
            Self::Unresolved(name) => name.to_owned(),
            Self::Resolved(name, _) => name.to_owned(),
        }
    }
}