From 11a5777eabcdb44912dc107589448c57b31a5444 Mon Sep 17 00:00:00 2001 From: Pantonshire Date: Sat, 22 May 2021 11:49:14 +0100 Subject: [PATCH] Documentation --- enumscribe/src/lib.rs | 24 +++-- enumscribe_derive/src/lib.rs | 165 ++++++++++++++++++++++++++++++++++- 2 files changed, 179 insertions(+), 10 deletions(-) diff --git a/enumscribe/src/lib.rs b/enumscribe/src/lib.rs index be18faa..eac0fe2 100644 --- a/enumscribe/src/lib.rs +++ b/enumscribe/src/lib.rs @@ -169,7 +169,8 @@ use std::borrow::Cow; /// Trait for converting an enum to a static string slice. /// /// Like all of the traits provided by enumscribe, this should not be implemented manually; use -/// `#[derive(ScribeStaticStr)]` provided by the [enumscribe_derive] crate instead. +/// [`#[derive(ScribeStaticStr)]`](derive.ScribeStaticStr.html) provided by the +/// [enumscribe_derive] crate instead. /// /// When deriving this trait, you may specify the string that a particular variant should be /// converted to by annotating it with `#[enumscribe(str = "foo")]`. If this is omitted, the name @@ -185,7 +186,8 @@ pub trait ScribeStaticStr { /// Trait for converting an enum to a static string slice, or `None` if the conversion fails. /// /// Like all of the traits provided by enumscribe, this should not be implemented manually; use -/// `#[derive(TryScribeStaticStr)]` provided by the [enumscribe_derive] crate instead. +/// [`#[derive(TryScribeStaticStr)]`](derive.TryScribeStaticStr.html) provided by the +/// [enumscribe_derive] crate instead. /// /// When deriving this trait, you may specify the string that a particular variant should be /// converted to by annotating it with `#[enumscribe(str = "foo")]`. If this is omitted, the name @@ -204,7 +206,8 @@ pub trait TryScribeStaticStr { /// preferred over this trait because it avoids unnecessary allocations. /// /// Like all of the traits provided by enumscribe, this should not be implemented manually; use -/// `#[derive(ScribeString)]` provided by the [enumscribe_derive] crate instead. +/// [`#[derive(ScribeString)]`](derive.ScribeString.html) provided by the +/// [enumscribe_derive] crate instead. /// /// This trait can only be used if none of the enum's variants use `ignore`. pub trait ScribeString { @@ -216,7 +219,8 @@ pub trait ScribeString { /// allocations. /// /// Like all of the traits provided by enumscribe, this should not be implemented manually; use -/// `#[derive(TryScribeString)]` provided by the [enumscribe_derive] crate instead. +/// [`#[derive(TryScribeString)]`](derive.TryScribeString.html) provided by the +/// [enumscribe_derive] crate instead. pub trait TryScribeString { fn try_scribe(&self) -> Option; } @@ -224,7 +228,8 @@ pub trait TryScribeString { /// Trait for converting an enum to a clone-on-write string. /// /// Like all of the traits provided by enumscribe, this should not be implemented manually; use -/// `#[derive(ScribeCowStr)]` provided by the [enumscribe_derive] crate instead. +/// [`#[derive(ScribeCowStr)]`](derive.ScribeCowStr.html) provided by the +/// [enumscribe_derive] crate instead. /// /// When deriving this trait, you may specify the string that a particular variant should be /// converted to by annotating it with `#[enumscribe(str = "foo")]`. If this is omitted, the name @@ -243,7 +248,8 @@ pub trait ScribeCowStr { /// Trait for converting an enum to a clone-on-write string, or `None` if the conversion fails. /// /// Like all of the traits provided by enumscribe, this should not be implemented manually; use -/// `#[derive(TryScribeCowStr)]` provided by the [enumscribe_derive] crate instead. +/// [`#[derive(TryScribeCowStr)]`](derive.TryScribeCowStr.html) provided by the +/// [enumscribe_derive] crate instead. /// /// When deriving this trait, you may specify the string that a particular variant should be /// converted to by annotating it with `#[enumscribe(str = "foo")]`. If this is omitted, the name @@ -262,7 +268,8 @@ pub trait TryScribeCowStr { /// Trait for converting from a string to an enum. /// /// Like all of the traits provided by enumscribe, this should not be implemented manually; use -/// `#[derive(Unscribe)]` provided by the [enumscribe_derive] crate instead. +/// [`#[derive(Unscribe)]`](derive.Unscribe.html) provided by the +/// [enumscribe_derive] crate instead. /// /// When deriving this trait, you may specify the string that should map to a particular variant /// by annotating it with `#[enumscribe(str = "foo")]`. If this is omitted, the name of the variant @@ -280,7 +287,8 @@ pub trait Unscribe: Sized { /// Trait for converting from a string to an enum, or `None` if the conversion fails. /// /// Like all of the traits provided by enumscribe, this should not be implemented manually; use -/// `#[derive(TryUnscribe)]` provided by the [enumscribe_derive] crate instead. +/// [`#[derive(TryUnscribe)]`](derive.TryUnscribe.html) provided by the +/// [enumscribe_derive] crate instead. /// /// Annotating a variant with `#[enumscribe(case_insensitive)]` will cause case insensitive matching /// to be used for that variant. If it is omitted, matching will be case sensitive. diff --git a/enumscribe_derive/src/lib.rs b/enumscribe_derive/src/lib.rs index 59d3035..943cace 100644 --- a/enumscribe_derive/src/lib.rs +++ b/enumscribe_derive/src/lib.rs @@ -1,6 +1,7 @@ //! Derive macros for the traits provided by `enumscribe`, to help you easily convert your enums -//! to strings and vice-versa. See the `enumscribe` crate's documentation for information on -//! deriving these traits. +//! to strings and vice-versa. +//! +//! See the documentation for the `enumscribe` crate for usage examples. use proc_macro::TokenStream; @@ -269,6 +270,30 @@ fn gen_unscribe_match( Ok(main_match) } +/// Derives `enumscribe::ScribeStaticStr` for an enum. This allows the enum to be converted to +/// a `&'static str` using the `scribe()` method. +/// +/// You may annotate variants with `#[enumscribe(str = "foo")]` to specify what string the variant +/// should be converted to (replacing `"foo"` with a string of your choice). If this is omitted, +/// the name of the variant will be used instead. Using the same string for two variants of the +/// same enum will cause a compile-time error. +/// +/// Other derive macros in this crate allow you to use attributes like `#[enumscribe(other)]` +/// and `#[enumscribe(ignore)]`, where `other` allows you to specify a variant that should be used +/// to store strings that could not be matched to any other variant, and `ignore` lets you tell +/// `enumscribe` not to consider a particular variant when deriving traits. However, using either +/// of these attributes when deriving `ScribeStaticStr` will cause a compile-time error; if these +/// attributes are used, then there are some cases where it would be impossible to return +/// a meaningful `&'static str`. +/// +/// If you want to use `#[enumscribe(other)]`, try deriving +/// [`ScribeCowStr`](derive.ScribeCowStr.html) instead. +/// +/// If you want to use `#[enumscribe(ignore)]`, try deriving +/// [`TryScribeStaticStr`](derive.TryScribeStaticStr.html) instead. +/// +/// If you want to use both, try deriving +/// [`TryScribeCowStr`](derive.TryScribeCowStr.html) instead. #[proc_macro_derive(ScribeStaticStr, attributes(enumscribe))] pub fn derive_scribe_static_str(input: TokenStream) -> TokenStream { gen_scribe_impl( @@ -296,6 +321,21 @@ pub fn derive_scribe_static_str(input: TokenStream) -> TokenStream { ) } +/// Derives `enumscribe::TryScribeStaticStr` for an enum. This allows the enum to be converted to +/// a `Option<&'static str>` using the `try_scribe()` method. +/// +/// You may annotate variants with `#[enumscribe(str = "foo")]` to specify what string the variant +/// should be converted to (replacing `"foo"` with a string of your choice). If this is omitted, +/// the name of the variant will be used instead. Using the same string for two variants of the +/// same enum will cause a compile-time error. +/// +/// This is a version of [`ScribeStaticStr`](derive.ScribeStaticStr.html) intended to be used if +/// you have one or more variants annotated with `#[enumscribe(ignore)]`. Calling `try_scribe()` +/// on an ignored variant will always return `None`. +/// +/// Like [`ScribeStaticStr`](derive.ScribeStaticStr.html), you may not use `#[enumscribe(other)]` +/// when deriving this trait. If you want to use `other`, try deriving +/// [`TryScribeCowStr`](derive.TryScribeCowStr.html) instead. #[proc_macro_derive(TryScribeStaticStr, attributes(enumscribe))] pub fn derive_try_scribe_static_str(input: TokenStream) -> TokenStream { gen_try_scribe_impl( @@ -319,6 +359,15 @@ pub fn derive_try_scribe_static_str(input: TokenStream) -> TokenStream { ) } +/// Derives `enumscribe::ScribeString` for an enum. This allows the enum to be converted to +/// a `String` using the `scribe()` method. +/// +/// This behaves almost identically to [`ScribeCowStr`](derive.ScribeCowStr.html), except the +/// return type is `String` instead of `Cow<'static, str>`. +/// +/// Since a `String` is returned, an allocation must always be performed, which is wasteful. +/// [`ScribeCowStr`](derive.ScribeCowStr.html) should be preferred because it avoids unnecessary +/// allocations. #[proc_macro_derive(ScribeString, attributes(enumscribe))] pub fn derive_scribe_string(input: TokenStream) -> TokenStream { gen_scribe_impl( @@ -345,6 +394,15 @@ pub fn derive_scribe_string(input: TokenStream) -> TokenStream { ) } +/// Derives `enumscribe::TryScribeString` for an enum. This allows the enum to be converted to +/// a `Option` using the `try_scribe()` method. +/// +/// This behaves almost identically to [`TryScribeCowStr`](derive.TryScribeCowStr.html), except the +/// return type is `Option` instead of `Option>`. +/// +/// Since a `String` is returned, an allocation must always be performed, which is wasteful. +/// [`TryScribeCowStr`](derive.TryScribeCowStr.html) should be preferred because it avoids +/// unnecessary allocations. #[proc_macro_derive(TryScribeString, attributes(enumscribe))] pub fn derive_try_scribe_string(input: TokenStream) -> TokenStream { gen_try_scribe_impl( @@ -369,6 +427,25 @@ pub fn derive_try_scribe_string(input: TokenStream) -> TokenStream { ) } +/// Derives `enumscribe::ScribeCowStr` for an enum. This allows the enum to be converted to +/// a `Cow<'static, str>` using the `scribe()` method. +/// +/// You may annotate variants with `#[enumscribe(str = "foo")]` to specify what string the variant +/// should be converted to (replacing `"foo"` with a string of your choice). If this is omitted, +/// the name of the variant will be used instead. Using the same string for two variants of the +/// same enum will cause a compile-time error. +/// +/// This derive also supports annotating a variant with `#[enumscibe(other)]`, which is useful +/// because it is required to derive [`Unscribe`](derive.Unscribe.html). This allows you to +/// specify that a variant should be used to store strings that could not be matched to any other +/// variant when unscribing. The variant should have a single field, which should have type +/// `String`. +/// +/// If you do not want to use `#[enumscribe(other)]`, you should derive +/// [`ScribeStaticStr`](derive.ScribeStaticStr.html) instead. +/// +/// This derive does not support ignoring variants with `#[enumscribe(ignore)]`. If you want to +/// ignore variants, try deriving [`TryScribeCowStr`](derive.TryScribeCowStr.html) instead. #[proc_macro_derive(ScribeCowStr, attributes(enumscribe))] pub fn derive_scribe_cow_str(input: TokenStream) -> TokenStream { gen_scribe_impl( @@ -397,6 +474,26 @@ pub fn derive_scribe_cow_str(input: TokenStream) -> TokenStream { ) } +/// Derives `enumscribe::TryScribeCowStr` for an enum. This allows the enum to be converted to +/// a `Option>` using the `try_scribe()` method. +/// +/// You may annotate variants with `#[enumscribe(str = "foo")]` to specify what string the variant +/// should be converted to (replacing `"foo"` with a string of your choice). If this is omitted, +/// the name of the variant will be used instead. Using the same string for two variants of the +/// same enum will cause a compile-time error. +/// +/// This is a version of [`ScribeCowStr`](derive.ScribeCowStr.html) intended to be used if +/// you have one or more variants annotated with `#[enumscribe(ignore)]`. Calling `try_scribe()` +/// on an ignored variant will always return `None`. +/// +/// This derive also supports annotating a variant with `#[enumscibe(other)]`, which is useful +/// because it is required to derive [`Unscribe`](derive.Unscribe.html). This allows you to +/// specify that a variant should be used to store strings that could not be matched to any other +/// variant when unscribing. The variant should have a single field, which should have type +/// `String`. +/// +/// If you do not want to use `#[enumscribe(other)]`, you should derive +/// [`TryScribeStaticStr`](derive.TryScribeStaticStr.html) instead. #[proc_macro_derive(TryScribeCowStr, attributes(enumscribe))] pub fn derive_try_scribe_cow_str(input: TokenStream) -> TokenStream { gen_try_scribe_impl( @@ -423,6 +520,27 @@ pub fn derive_try_scribe_cow_str(input: TokenStream) -> TokenStream { ) } +/// Derives `enumscribe::Unscribe` for an enum. This allows a `&str` to be converted to the +/// enum using the `unscribe()` associated function. +/// +/// You may annotate variants with `#[enumscribe(str = "foo")]` to specify what string should +/// convert to the variant (replacing `"foo"` with a string of your choice). If this is omitted, +/// the name of the variant will be used instead. Using the same string for two variants of the +/// same enum will cause a compile-time error. +/// +/// You may annotate a variant with `#[enumscribe(case_insensitive)]` to use case-insensitive +/// matching for that variant. For example, if a variant is annotated with +/// `#[enumscribe(str = "baa", case_insensitive)]`, then strings like `"baa"`, `"BAA"`, `"bAa"` +/// etc. will all be matched to that variant. +/// +/// In order to derive this trait, you must have exactly one variant annotated with +/// `#[enumscribe(other)]`. This variant will be used to store any string that could not be matched +/// to any of the other variants. The variant must have exactly one field, which should have type +/// `String`. Both named (`Variant { name: String }`) and unnamed (`Variant(String)`) fields are +/// allowed. +/// +/// If you do not want to use `#[enumscribe(other)]`, try deriving +/// [`TryUnscribe`](derive.TryUnscribe.html) instead. #[proc_macro_derive(Unscribe, attributes(enumscribe))] pub fn derive_unscribe(input: TokenStream) -> TokenStream { gen_unscribe_impl( @@ -446,6 +564,24 @@ pub fn derive_unscribe(input: TokenStream) -> TokenStream { ) } +/// Derives `enumscribe::TryUnscribe` for an enum. This allows a `&str` to be converted to an +/// `Option` of the enum using the `try_unscribe()` associated function. +/// +/// You may annotate variants with `#[enumscribe(str = "foo")]` to specify what string should +/// convert to the variant (replacing `"foo"` with a string of your choice). If this is omitted, +/// the name of the variant will be used instead. Using the same string for two variants of the +/// same enum will cause a compile-time error. +/// +/// You may annotate a variant with `#[enumscribe(case_insensitive)]` to use case-insensitive +/// matching for that variant. For example, if a variant is annotated with +/// `#[enumscribe(str = "baa", case_insensitive)]`, then strings like `"baa"`, `"BAA"`, `"bAa"` +/// etc. will all be matched to that variant. +/// +/// Unlike [`Unscribe`](derive.Unscribe.html), there is no requirement to have a variant annotated +/// with `#[enumscribe(other)]`, although you may use it if you want. If there is an `other` +/// variant, then the `other` variant will be returned when a string could not be matched to any +/// other variant. If there is no `other` variant, `None` will be returned when a string could not +/// be matched to any other variant. #[proc_macro_derive(TryUnscribe, attributes(enumscribe))] pub fn derive_try_unscribe(input: TokenStream) -> TokenStream { gen_unscribe_impl( @@ -463,6 +599,15 @@ pub fn derive_try_unscribe(input: TokenStream) -> TokenStream { ) } +/// Derives `serde::Serialize` for an enum. +/// +/// The enum will be serialized to a string. You can specify what string should be used to +/// represent a particular variant by using `#[enumscribe(str = "foo")]`, just like the other +/// derive macros in this crate. +/// +/// This derive also allows you to use `#[enumscribe(other)]` and `#[enumscribe(ignore)]`. +/// Trying to serialize an ignored variant will result in an error being returned. Serializing +/// an `other` variant will simply use whatever the value of its field is. #[cfg(feature = "serde")] #[proc_macro_derive(EnumSerialize, attributes(enumscribe))] pub fn derive_enum_serialize(input: TokenStream) -> TokenStream { @@ -540,6 +685,22 @@ pub fn derive_enum_serialize(input: TokenStream) -> TokenStream { }).into() } +/// Derives `serde::Deserialize` for an enum. +/// +/// The enum will be deserialized from a string. If the input was not a valid string, an error +/// will be returned. You can specify what string should map to a particular variant by using +/// `#[enumscribe(str = "foo")]`, just like the other derive macros in this crate. You can also +/// use `#[enumscribe(case_insensitive)]` to use case-insensitive matching for a variant, like +/// [`Unscribe`](derive.Unscribe.html) and [`TryUnscribe`](derive.TryUnscribe.html). +/// +/// Also like [`Unscribe`](derive.Unscribe.html), you can annotate a variant with +/// `#[enumscribe(other)]`. If included, the `other` variant will be used to store strings that +/// could not be matched to any other variant. The `other` variant should have a single field, +/// which should have type `String`. If an `other` variant is not included, an error will be +/// returned when a string could not be matched to any variant. +/// +/// This derive also allows you to use `#[enumscribe(ignore)]`. No string will ever deserialize +/// to an ignored variant. #[cfg(feature = "serde")] #[proc_macro_derive(EnumDeserialize, attributes(enumscribe))] pub fn derive_enum_deserialize(input: TokenStream) -> TokenStream {