|
…
|
||
|---|---|---|
| .. | ||
| src | ||
| .cargo-checksum.json | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
Checked owned and borrowed strings.
Overview
The Rust standard library provides the String and str types, which wrap
Vec<u8> and [u8] respectively, with the invariant that the contents
are valid UTF-8.
This crate abstracts the idea of type-level invariants on strings by
introducing the immutable Check and Ck types, where the invariants
are determined by a generic Invariant type parameter. Implementing
the Invariant trait is left to other crates, such as strck_ident.
"strck" comes from "str check", similar to how rustc has typeck and borrowck for type check and borrow check respectively.
See the documentation for more details.
Motivation
Libraries working with string-like types with certain properties, like identifiers,
quickly become confusing as &str and String begin to pollute type signatures
everywhere. One solution is to manually implement an owned checked string type
like syn::Ident to disambiguate the type signatures and validate the string.
The downside is that new values cannot be created without allocation,
which is unnecessary when only a borrowed version is required.
strck solves this issue by providing a checked borrowed string type, Ck,
alongside a checked owned string type, Check. These serve as thin wrappers
around str and String1 respectively, and prove at the type level that
the contents satisfy the Invariant that the wrapper is generic over.
Use cases
Checked strings without allocating
The main benefit strck offers is validating borrowed strings via the
Ck type without having to allocate in the result.
use strck_ident::{Ck, IntoCk, rust::RustIdent};
let this_ident: &Ck<RustIdent> = "this".ck().unwrap();
Checked zero-copy deserialization
When the serde feature flag is enabled, Cks can be used to perform
checked zero-copy deserialization, which requires the
#[serde(borrow)] attribute.
use strck_ident::{Ck, unicode::UnicodeIdent};
#[derive(Serialize, Deserialize)]
struct Player<'a> {
#[serde(borrow)]
username: &'a Ck<UnicodeIdent>,
level: u32,
}
Note that this code sample explicitly uses Ck<UnicodeIdent> to demonstrate
that the type is a Ck. However, strck_ident provides Ident as an
alias for Ck<UnicodeIdent>, which should be used in practice.
Infallible parsing
For types where string validation is relatively cheap but parsing is costly
and fallible, strck can be used with a custom Invariant as an input to
make an infallible parsing function.
Postfix construction with IntoCk and IntoCheck
This crate exposes two helper traits, IntoCk and IntoCheck. When in
scope, the .ck() and .check() functions can be used to create
Cks and Checks respectively:
use strck_ident::{IntoCheck, IntoCk, unicode::UnicodeIdent};
let this_ident = "this".ck::<UnicodeIdent>().unwrap();
let this_foo_ident = format!("{}_foo", this_ident).check::<UnicodeIdent>().unwrap();
Documentation
See the crate-level documentation for more details.
-
Checkcan actually be backed by any'static + AsRef<str>type, butStringis the default. ↩︎