Macro unic_char_property::char_property [] [src]

macro_rules! char_property {
    (
        $(#[$name_meta:meta])*
        pub enum $name:ident {
            abbr => $abbr_name:expr;
            long => $long_name:expr;
            human => $human_name:expr;

            $(
                $(#[$variant_meta:meta])+
                $variant:ident {
                    abbr => $abbr:ident,
                    long => $long:ident,
                    human => $human:expr,
                }
            )*
        }

        $(#[$abbr_mod_meta:meta])*
        pub mod $abbr_mod:ident for abbr;

        $(#[$long_mod_meta:meta])*
        pub mod $long_mod:ident for long;

    ) => { ... };
    (
        $(#[$name_meta:meta])*
        pub struct $name:ident(bool) {
            abbr => $abbr_name:expr;
            long => $long_name:expr;
            human => $human_name:expr;

            data_table_path => $data_path:expr;
        }

        $(#[$is_fn_meta:meta])*
        pub fn $is_fn:ident(char) -> bool;

    ) => { ... };
    (
        __impl CharProperty for $name:ident;
        $abbr:expr;
        $long:expr;
        $human:expr;
    ) => { ... };
    (
        __impl FromStr for $name:ident;
        $( $id:ident => $value:expr; )*
    ) => { ... };
    ( __impl Display for $name:ident by $trait:ident ) => { ... };
}

Macro for declaring a character property.

Syntax (Enumerated Property)

#[macro_use]
extern crate unic_char_property;

// First we define the type itself.
char_property! {
    /// This is the enum type created for the character property.
    pub enum MyProp {
        abbr => "AbbrPropName";
        long => "Long_Property_Name";
        human => "Human-Readable Property Name";

        /// Exactly one attribute
        RustName {
            abbr => AbbrName,
            long => Long_Name,
            human => "&'static str that is a nicer presentation of the name",
        }
    }

    /// Module aliasing property value abbreviated names.
    pub mod abbr_names for abbr;

    /// Module aliasing property value long names.
    pub mod long_names for long;
}

// We also need to impl `PartialCharProperty` or `TotalCharProperty` manually.

Syntax (Binary Property)

Be careful when using this code, it's not being tested!
#[macro_use] extern crate unic_char_property;

char_property! {
    /// This is the newtype used for the character property.
    pub struct MyProp(bool) {
        abbr => "AbbrPropName";
        long => "Long_Property_Name";
        human => "Human-Readable Property Name";

        // Unlike an enumerated property, a binary property will handle the table for you.
        data_table_path => "../tests/tables/property_table.rsv";
    }

    /// A function that returns whether the given character has the property or not.
    pub fn is_prop(char) -> bool;
}

// You may also want to create a trait for easy access to the properties you define.

Effect

  • Implements the CharProperty trait and appropriate range trait
  • Implements FromStr accepting either the abbr or long name, ascii case insensitive
  • Implements Display using the human string
  • Populates the module abbr_names with pub use bindings of variants to their abbr names (Enumerated properties only)
  • Populates the module long_names with pub use bindings of variants to their long names (Enumerated properties only)
  • Maintains all documentation comments and other #[attributes] as would be expected (with some limitations, listed below)

Limitations

Due to rust-lang/rust#24189, (fixed in rust-lang/rust#42913, landing in 1.20), exactly one attribute line must be used on each variant.

On 1.20 or higher, one or more may be used, and the restriction can be relaxed back to the intended zero or more by replacing $(#[$variant_meta:meta])+ with $(#[$variant_meta:meta])* and $(#[$variant_meta])+ with $(#[$variant_meta])*.