No description
  • Rust 99.2%
  • Shell 0.8%
Find a file
Sam Johnson fa75da82c0
Some checks failed
CI Checks / cargo test (push) Has been cancelled
CI Checks / cargo fmt (push) Has been cancelled
CI Checks / cargo doc (push) Has been cancelled
bump to v0.1.7
2023-07-19 23:58:37 -04:00
.github/workflows add CI 2023-07-06 17:59:58 -04:00
macros bump to v0.1.7 2023-07-19 23:58:37 -04:00
src fix doc link elsewhere 2023-07-19 23:56:16 -04:00
tests add tests for custom alphabets 2023-07-12 23:48:55 -04:00
.gitignore initial commit 2023-07-06 16:07:44 -04:00
Cargo.toml bump to v0.1.7 2023-07-19 23:58:37 -04:00
LICENSE add MIT license 2023-07-07 02:31:11 -04:00
publish.sh add publish.sh script 2023-07-07 00:38:12 -04:00
README.docify.md fix doc link elsewhere 2023-07-19 23:56:16 -04:00
README.md Fixed link to docs 2023-07-15 12:08:15 -03:00

smol-symbol 💠

Crates.io docs.rs Build Status MIT License

This crate provides the ability to create globally unique (per input value), human-readable Symbols at compile-time as well as at run-time, that are meant to be reminiscent of the Symbol type in the Crystal programming language.

Where this crate differs is the alphabet and length of our Symbol is a bit more restrictive, allowing us to encode the entire text of each Symbol as a u128 internally. The only caveat is we are limited to 25 characters of length and an alphabet consisting of lowercase a-z as well as _. No other characters are permitted.

The Symbol type can be created at compile-time using the convenient s! macro, and can also be created using the TryFrom<AsRef<str>> impl at runtime, though this is not as efficient as doing this at compile-time using the s! macro.

The Symbol type can also be turned into a String via a convenient Into<String> impl.

We also provide the ability to define custom alphabets that use the more general CustomSymbol type via a handy custom_alphabet! macro, allowing you to alter these restrictions directly (smaller alphabet = larger max length for a symbol) and add support for other languages or less restrictive character sets. The only invariant that can't be customized at the moment is CustomSymbol will always use a u128 as its backing data store.

Example

#[test]
fn symbol_example() {
    // Symbols can be stored in variables
    let sym1 = s!(hello_world);

    // Symbols can be used in const contexts
    const SYM2: Symbol = s!(goodnight);

    // Symbols can be compared with each other
    let sym3 = s!(hello_world);
    assert_eq!(sym1, sym3);
    assert_ne!(sym1, SYM2);
    assert_ne!(s!(this_is_a_triumph), s!(im_making_a_note_here));

    // Symbols are 16 bytes
    assert_eq!(std::mem::size_of_val(&sym1), 16);
    assert_eq!(std::mem::size_of_val(&sym1), std::mem::size_of::<u128>());

    // Symbols can even be created dynamically at runtime!
    let some_string = String::from("some_random_string");
    let dynamic_sym = Symbol::try_from(some_string).unwrap();
    assert_eq!(dynamic_sym, s!(some_random_string));

    // Can't be longer than 25 characters
    assert!(Symbol::try_from("this_is_too_long_to_store_").is_err());
    assert!(Symbol::try_from("this_is_just_short_enough").is_ok());

    // Character alphabet is limited to lowercase a-z and _
    assert!(Symbol::try_from("this-is-invalid").is_err());
    assert!(Symbol::try_from("this is_invalid").is_err());
    assert!(Symbol::try_from("this.is.invalid").is_err());
}

See the docs for Symbol and s! for more detailed information.