tstr/
lib.rs

1//! This crate provides an encoding of type-level strings as types.
2//!
3//! # Examples
4//!
5//! ### Indexing
6//!
7//! This example demonstrates how you can use type-level strings,
8//! and the [`Index`] trait, to access fields of generic types by name.
9//!
10//! ```
11//! use std::ops::Index;
12//!
13//! use tstr::{TS, ts};
14//!
15//! fn main(){
16//!     takes_person(&Person::new("Bob".into(), "Marley".into()));
17//!
18//!     takes_person(&OtherPerson::new("Bob", "Marley"));
19//! }
20//!
21//! fn takes_person<P>(pers: &P)
22//! where
23//!     P: Index<TS!(name), Output = str> + Index<TS!(surname), Output = str>
24//! {
25//!     assert_eq!(&pers[ts!(name)], "Bob");
26//!     assert_eq!(&pers[ts!(surname)], "Marley");
27//! }
28//!
29//!
30//! use person::Person;
31//! mod person {
32//!     use std::ops::Index;
33//!
34//!     use tstr::TS;
35//!     
36//!     pub struct Person {
37//!         name: String,
38//!         surname: String,
39//!     }
40//!     
41//!     impl Person {
42//!         pub fn new(name: String, surname: String) -> Self {
43//!             Self{name, surname}
44//!         }
45//!     }
46//!     
47//!     impl Index<TS!(name)> for Person {
48//!         type Output = str;
49//!         
50//!         fn index(&self, _: TS!(name)) -> &str {
51//!             &self.name
52//!         }
53//!     }
54//!    
55//!     impl Index<TS!(surname)> for Person {
56//!         type Output = str;
57//!         
58//!         fn index(&self, _: TS!(surname)) -> &str {
59//!             &self.surname
60//!         }
61//!     }
62//! }
63//!
64//! use other_person::OtherPerson;
65//! mod other_person {
66//!     use std::ops::Index;
67//!
68//!     use tstr::TS;
69//!     
70//!     pub struct OtherPerson {
71//!         name: &'static str,
72//!         surname: &'static str,
73//!     }
74//!     
75//!     impl OtherPerson {
76//!         pub fn new(name: &'static str, surname: &'static str) -> Self {
77//!             Self{name, surname}
78//!         }
79//!     }
80//!     
81//!     impl Index<TS!(name)> for OtherPerson {
82//!         type Output = str;
83//!         
84//!         fn index(&self, _: TS!(name)) -> &str {
85//!             self.name
86//!         }
87//!     }
88//!    
89//!     impl Index<TS!(surname)> for OtherPerson {
90//!         type Output = str;
91//!         
92//!         fn index(&self, _: TS!(surname)) -> &str {
93//!             self.surname
94//!         }
95//!     }
96//! }
97//!
98//! ```
99//!
100//! # Macro expansion
101//!
102//! This library reserves the right to change how it represent type-level strings internally
103//! in every single release, and cargo feature combination.
104//!
105//! This only affects you if you expand the code generated by macros from this crate,
106//! and then use that expanded code instead of going through the macros.
107//!
108//! # Cargo features
109//!
110//! - `"rust_1_46"`:
111//! Enables const functions in [`tstr::utils`] for comparing `&str` and `&[u8]`.
112//!
113//! - `"cmp_traits"`: Enables the traits for comparing type-level strings.
114//!
115//! - `"use_syn"`:
116//! Changes how literals passed to the macros of this crate are parsed to use the `syn` crate.
117//! Use this if there is some literal that could not be
118//! parsed but is a valid str/integer literal.
119//!
120//! - `"min_const_generics"`:
121//! changes the representation of type-level strings to use many `char` const parameter,
122//! making for better compiler errors for non-alphanumeric-ascii strings.
123//! Requires Rust 1.51.0.
124//!
125//! - `"const_generics"`:
126//! Changes the representation of type-level strings to use a `&'static str` const parameter,
127//! making for better compiler errors, and a few more features.
128//! As of 2023-03-17, this feature can't be enabled, because it
129//! requires `&'static str` to be stably usable as const parameters.
130//! Consider using `"nightly_const_generics"` if this feature can't be used.
131//!
132//! - `"nightly_const_generics"`: Equivalent to the `"const_generics"` feature,
133//! and enables the nightly compiler features to use `&'static str` const parameters.//!
134//!
135//! - `"for_examples"`: Enables the `for_examples` module,
136//! with a few types used in documentation examples.
137//!
138//! # No-std support
139//!
140//! This crate is unconditionally `#![no_std]`, and can be used anywhere that Rust can be.
141//!
142//! # Minimum Supported Rust Version
143//!
144//! This crate supports Rust versions back to Rust 1.40.0.
145//!
146//! [`Index`]: https://doc.rust-lang.org/std/ops/trait.Index.html
147//! [`tstr::utils`]: ./utils/index.html
148#![no_std]
149#![cfg_attr(feature = "nightly_const_generics", feature(adt_const_params))]
150#![cfg_attr(feature = "docsrs", feature(doc_cfg, doc_auto_cfg))]
151#![allow(non_camel_case_types)]
152#![cfg_attr(feature = "nightly_const_generics", allow(incomplete_features))]
153
154#[cfg(feature = "for_examples")]
155#[cfg_attr(feature = "docsrs", doc(cfg(feature = "for_examples")))]
156pub mod for_examples;
157
158#[cfg(not(feature = "const_generics"))]
159#[cfg(feature = "cmp_traits")]
160mod for_tupled_reprs;
161
162pub mod asserts;
163
164mod macros;
165mod make_tstr;
166mod to_uint;
167mod tstr_type;
168
169#[cfg(feature = "cmp_traits")]
170mod tstr_cmp;
171
172pub mod utils;
173
174#[doc(hidden)]
175extern crate self as tstr;
176
177#[doc(hidden)]
178pub use tstr_proc_macros::__ts_impl;
179
180pub use crate::{asserts::Assert, make_tstr::MakeTStr, to_uint::ToUint, tstr_type::TStr};
181
182#[cfg(feature = "cmp_traits")]
183pub use tstr_cmp::TStrEq;
184
185#[cfg(all(feature = "cmp_traits", feature = "const_generics"))]
186pub use tstr_cmp::TStrOrd;
187
188#[cfg_attr(feature = "docsrs", doc(cfg(feature = "const_generics")))]
189#[cfg(feature = "const_generics")]
190pub use crate::tstr_type::StrValue;
191
192include! {"./p.rs"}