meta_merge_core 0.1.0

Core logic for meta_merge
Documentation
use crate::extensions::token_stream::{PathTokenStreamFromStr, PathTokenStreamFromStrCollection};
use const_format::concatcp;

pub mod apply;
pub mod copy;
pub mod export;
pub mod merge;

pub mod prelude {
    use super::*;
    pub use apply::apply_outer;
    pub use copy::copy_attr_outer;
    pub use export::export_attr_outer;
    pub use merge::merge_attr_outer;
    use proc_macro2::TokenStream;
    use syn::spanned::Spanned;
    pub fn error(ts: impl Into<TokenStream>, message: &str) -> TokenStream {
        syn::Error::new(ts.into().span(), message).to_compile_error()
    }
}

type StaticStr = &'static str;
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct ApiPaths {
    root: StaticStr,
    copy_source_start: StaticStr,
    copy_source_end: StaticStr,
    merge_source_start: StaticStr,
    merge_source_end: StaticStr,
    export: StaticStr,
}

impl Default for ApiPaths {
    fn default() -> Self {
        ApiPaths::DEFAULT
    }
}

impl From<StaticStr> for ApiPaths {
    fn from(root: StaticStr) -> Self {
        Self::from_root(root)
    }
}

impl From<&ApiPaths> for ApiPaths {
    fn from(api_paths: &ApiPaths) -> Self {
        *api_paths
    }
}

macro_rules! make_path2 {
    ($self:ident, $field:ident) => {{
        PathTokenStreamFromStrCollection::new([
            $self.root(),
            PathTokenStreamFromStr::new($self.$field),
        ])
    }};
}

impl ApiPaths {
    const PRIVATE_EXPORT: &str = "__private";
    pub const DEFAULT: Self = Self {
        root: "meta_merge",
        copy_source_start: concatcp!(ApiPaths::PRIVATE_EXPORT, "::copy::source_start"),
        copy_source_end: concatcp!(ApiPaths::PRIVATE_EXPORT, "::copy::source_end"),
        merge_source_start: concatcp!(ApiPaths::PRIVATE_EXPORT, "::merge::source_start"),
        merge_source_end: concatcp!(ApiPaths::PRIVATE_EXPORT, "::merge::source_end"),
        export: concatcp!(ApiPaths::PRIVATE_EXPORT, "::export"),
    };

    pub const fn from_root(root: StaticStr) -> Self {
        Self {
            root,
            ..Self::DEFAULT
        }
    }

    const fn root(&self) -> PathTokenStreamFromStr<'_> {
        PathTokenStreamFromStr::new(self.root)
    }
    const fn copy_source_start(&self) -> PathTokenStreamFromStrCollection<'_, 2> {
        make_path2!(self, copy_source_start)
    }
    const fn copy_source_end(&self) -> PathTokenStreamFromStrCollection<'_, 2> {
        make_path2!(self, copy_source_end)
    }
    const fn merge_source_start(&self) -> PathTokenStreamFromStrCollection<'_, 2> {
        make_path2!(self, merge_source_start)
    }
    const fn merge_source_end(&self) -> PathTokenStreamFromStrCollection<'_, 2> {
        make_path2!(self, merge_source_end)
    }
    #[allow(dead_code)]
    const fn export(&self) -> PathTokenStreamFromStrCollection<'_, 2> {
        make_path2!(self, export)
    }
}

#[cfg(test)]
mod test_paths {
    use crate::extensions::token_stream::PathTokenStreamFromStrCollection;
    use crate::macro_api::ApiPaths;

    //noinspection SpellCheckingInspection
    #[allow(clippy::upper_case_acronyms)]
    type PTSFSC = PathTokenStreamFromStrCollection<'static, 2>;

    pub const API_PATHS: ApiPaths = ApiPaths::DEFAULT;
    pub const ATTR_EXPORT: PTSFSC = API_PATHS.export();
    pub const ATTR_COPY_SOURCE_START: PTSFSC = API_PATHS.copy_source_start();
    pub const ATTR_COPY_SOURCE_END: PTSFSC = API_PATHS.copy_source_end();
    pub const ATTR_MERGE_SOURCE_START: PTSFSC = API_PATHS.merge_source_start();
    pub const ATTR_MERGE_SOURCE_END: PTSFSC = API_PATHS.merge_source_end();
}