### Multiple Arguments for Format Strings Source: https://docs.rs/displaystr/latest/displaystr When using multiple arguments in `format_args!`, supply them as a tuple to the string literal. This example demonstrates formatting a `Vec`. ```rust use displaystr::display; #[display] pub enum DataStoreError { Redaction(String, Vec) = ( "the data for key `{_0}` is not available, but we recovered: {}", _1.join("+"), ), } ``` ```rust use displaystr::display; pub enum DataStoreError { Redaction(String, Vec), } impl ::core::fmt::Display for DataStoreError { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { match self { Self::Redaction(_0, _1) => f.write_fmt(format_args!( "the data for key `{_0}` is not available, but we recovered: {}", _1.join("+") )), } } } ``` -------------------------------- ### displaystr with thiserror Source: https://docs.rs/displaystr/latest/displaystr This example shows how to combine `displaystr` with the `thiserror` crate to define errors, leveraging `#[from]` for automatic conversion and `#[display]` for custom formatting. ```rust use thiserror::Error; use displaystr::display; #[derive(Error, Debug)] #[display] pub enum DataStoreError { Disconnect(#[from] io::Error) = "data store disconnected", Redaction(String) = "the data for key `{_0}` is not available", InvalidHeader { expected: String, found: String, } = "invalid header (expected {expected:?}, found {found:?})", Unknown = "unknown data store error", } ``` -------------------------------- ### Implement Display for Enums with displaystr Source: https://docs.rs/displaystr/latest/index.html Use the `#[display]` attribute macro on enums to automatically implement the `Display` trait. This example shows how to map enum variants to custom string formats, including those with arguments. ```rust use displaystr::display; #[display] pub enum DataStoreError { Disconnect(std::io::Error) = "data store disconnected", Redaction(String) = "the data for key `{_0}` is not available", InvalidHeader { expected: String, found: String, } = "invalid header (expected {expected:?}, found {found:?})", Unknown = "unknown data store error", } ``` ```rust use displaystr::display; pub enum DataStoreError { Disconnect(_0: std::io::Error), Redaction(_0: String), InvalidHeader { expected: String, found: String, }, Unknown, } impl ::core::fmt::Display for DataStoreError { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { match self { Self::Disconnect(_0) => { f.write_fmt(format_args!("data store disconnected")) } Self::Redaction(_0) => { f.write_fmt(format_args!("the data for key `{_0}` is not available")) } Self::InvalidHeader { expected, found } => { f.write_fmt(format_args!("invalid header (expected {expected}, found {found})")) } Self::Unknown => { f.write_fmt(format_args!("unknown data store error")) } } } } ``` -------------------------------- ### Enum Display Implementation with displaystr Source: https://docs.rs/displaystr/latest/displaystr Use the `#[display]` attribute macro to automatically implement the `Display` trait for enums. This example shows custom string literals for each variant, including named fields. ```rust use displaystr::display; #[display] pub enum DataStoreError { Disconnect(std::io::Error) = "data store disconnected", Redaction(String) = "the data for key `{_0}` is not available", InvalidHeader { expected: String, found: String, } = "invalid header (expected {expected:?}, found {found:?})", Unknown = "unknown data store error", } ``` ```rust use displaystr::display; pub enum DataStoreError { Disconnect(std::io::Error), Redaction(String), InvalidHeader { expected: String, found: String, }, Unknown, } impl ::core::fmt::Display for DataStoreError { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { match self { Self::Disconnect(_0) => { f.write_fmt(format_args!("data store disconnected")) } Self::Redaction(_0) => { f.write_fmt(format_args!("the data for key `{_0}` is not available")) } Self::InvalidHeader { expected, found } => { f.write_fmt(format_args!("invalid header (expected {expected}, found {found})")) } Self::Unknown => { f.write_fmt(format_args!("unknown data store error")) } } } } ``` -------------------------------- ### Comparison of Display implementations with displaystr, thiserror, and displaydoc Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Illustrates the equivalent enum definitions for `DataStoreError` using `displaystr`, `thiserror`, and `displaydoc` crates. This highlights the conciseness of `displaystr`. ```rust # use std::io; use thiserror::Error; use displaystr::display; #[derive(Error, Debug)] #[display] pub enum DataStoreError { Disconnect(#[from] io::Error) = "data store disconnected", Redaction(String) = "the data for key `{_0}` is not available", InvalidHeader { expected: String, found: String, } = "invalid header (expected {expected:?}, found {found:?})", Unknown = "unknown data store error", } ``` ```rust # use std::io; use thiserror::Error; #[derive(Error, Debug)] pub enum DataStoreError { #[error("data store disconnected")] Disconnect(#[from] io::Error), #[error("the data for key `{0}` is not available")] Redaction(String), #[error("invalid header (expected {expected:?}, found {found:?})")] InvalidHeader { expected: String, found: String, }, #[error("unknown data store error")] Unknown, } ``` ```rust # use std::io; use thiserror::Error; use displaydoc::Display; #[derive(Display, Error, Debug)] pub enum DataStoreError { /// data store disconnected Disconnect(#[source] io::Error), /// the data for key `{0}` is not available Redaction(String), /// invalid header (expected {expected:?}, found {found:?}) InvalidHeader { expected: String, found: String, }, /// unknown data store error Unknown, } ``` -------------------------------- ### Generate Doc Comment TokenTree Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Creates a `TokenTree` array representing a Rust doc comment (`///`). Useful for adding documentation to generated code. ```rust fn doc_comment(content: &str) -> [TokenTree; 2] { [ TokenTree::Punct(Punct::new('#', Spacing::Joint)), TokenTree::Group(Group::new( Delimiter::Bracket, TokenStream::from_iter([ TokenTree::Ident(Ident::new("doc", Span::call_site())), TokenTree::Punct(Punct::new('=', Spacing::Joint)), TokenTree::Literal(Literal::string(content)), ]), )), ] } ``` -------------------------------- ### Constructing the Display Implementation in Rust Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html This snippet shows the programmatic construction of the `impl Display` block for an enum using Rust's token stream API. It generates the `fmt` function with a `match` statement that iterates over enum variants. ```rust let display_impl = TokenStream::from_iter([ TokenTree::Ident(Ident::new("impl", Span::call_site())), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new("core", Span::call_site())), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new("fmt", Span::call_site())), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new("Display", Span::call_site())), TokenTree::Ident(Ident::new("for", Span::call_site())), TokenTree::Ident(enum_ident), TokenTree::Group(Group::new( Delimiter::Brace, TokenStream::from_iter([ TokenTree::Ident(Ident::new("fn", Span::call_site())), TokenTree::Ident(Ident::new("fmt", Span::call_site())), TokenTree::Group(Group::new( Delimiter::Parenthesis, TokenStream::from_iter([ TokenTree::Punct(Punct::new('&', Spacing::Joint)), TokenTree::Ident(Ident::new("self", Span::call_site())), TokenTree::Punct(Punct::new(',', Spacing::Joint)), TokenTree::Ident(Ident::new("f", Span::call_site())), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new('&', Spacing::Joint)), TokenTree::Ident(Ident::new("mut", Span::call_site())), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new("core", Span::call_site())), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new("fmt", Span::call_site())), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new("Formatter", Span::call_site())), ]), )), TokenTree::Punct(Punct::new('-', Spacing::Joint)), TokenTree::Punct(Punct::new('>', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new("core", Span::call_site())), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new("fmt", Span::call_site())), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new("Result", Span::call_site())), TokenTree::Group(Group::new( Delimiter::Brace, TokenStream::from_iter([ TokenTree::Ident(Ident::new("match", Span::call_site())), TokenTree::Ident(Ident::new("self", Span::call_site())), TokenTree::Group(Group::new(Delimiter::Brace, arms)), ]), )), ]), )), ]); ``` -------------------------------- ### Multiple Arguments for Format String Source: https://docs.rs/displaystr When a format string requires multiple arguments, use a tuple to provide them. The second element of the tuple can be an expression that operates on the variant's fields. ```rust use displaystr::display; #[display] pub enum DataStoreError { Redaction(String, Vec) = ( "the data for key `{_0}` is not available, but we recovered: {}", _1.join("+"), ), } ``` -------------------------------- ### Expanded Display Implementation for Enum Source: https://docs.rs/displaystr This shows the code generated by the `#[display]` macro for the `DataStoreError` enum, including the `impl Display` block. ```rust use displaystr::display; pub enum DataStoreError { Disconnect(std::io::Error), Redaction(String), InvalidHeader { expected: String, found: String, }, Unknown, } impl ::core::fmt::Display for DataStoreError { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { match self { Self::Disconnect(_0) => { f.write_fmt(format_args!("data store disconnected")) } Self::Redaction(_0) => { f.write_fmt(format_args!("the data for key `{_0}` is not available")) } Self::InvalidHeader { expected, found } => { f.write_fmt(format_args!("invalid header (expected {expected}, found {found})")) } Self::Unknown => { f.write_fmt(format_args!("unknown data store error")) } } } } ``` -------------------------------- ### Expanded Enum with Auto-generated Doc Comments Source: https://docs.rs/displaystr This illustrates the expansion of `#[display(doc)]`, showing how `///` comments are added to enum variants. ```rust use displaystr::display; pub enum DataStoreError { /// data store disconnected Disconnect(std::io::Error), /// the data for key `{_0}` is not available Redaction(String), /// invalid header (expected {expected:?}, found {found:?}) InvalidHeader { expected: String, found: String, }, /// unknown data store error Unknown, } // impl Display omitted since it's identical to the previous section ``` -------------------------------- ### Generate Doc Comments with displaystr Source: https://docs.rs/displaystr Use `#[display(doc)]` to automatically generate `///` doc comments for enum variants based on their associated format strings. ```rust use displaystr::display; #[display(doc)] pub enum DataStoreError { Disconnect(std::io::Error) = "data store disconnected", Redaction(String) = "the data for key `{_0}` is not available", InvalidHeader { expected: String, found: String, } = "invalid header (expected {expected:?}, found {found:?})", Unknown = "unknown data store error", } ``` -------------------------------- ### Enum Display with Multiple Arguments via Tuple Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html When a format string requires multiple arguments, provide them as a tuple in the variant definition. The second element of the tuple can be an expression that evaluates to the required arguments. ```rust use displaystr::display; #[display] pub enum DataStoreError { Redaction(String, Vec) = ( "the data for key `{_0}` is not available, but we recovered: {}", _1.join("+"), ), } impl ::core::fmt::Display for DataStoreError { ``` -------------------------------- ### Auto-generate Doc Comments with displaystr Source: https://docs.rs/displaystr/latest/displaystr Use `#[display(doc)]` to automatically generate `///` doc comments for enum variants based on their associated string literals. ```rust use displaystr::display; #[display(doc)] pub enum DataStoreError { Disconnect(std::io::Error) = "data store disconnected", Redaction(String) = "the data for key `{_0}` is not available", InvalidHeader { expected: String, found: String, } = "invalid header (expected {expected:?}, found {found:?})", Unknown = "unknown data store error", } ``` ```rust use displaystr::display; pub enum DataStoreError { /// data store disconnected Disconnect(std::io::Error), /// the data for key `{_0}` is not available Redaction(String), /// invalid header (expected {expected:?}, found {found:?}) InvalidHeader { expected: String, found: String, }, /// unknown data store error Unknown, } // impl Display omitted since it's identical to the previous section ``` -------------------------------- ### Generate Enum Variant Arm for Display Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Constructs a `DisplayArm` `TokenTree` array for an enum variant, suitable for implementing `fmt::Display`. It includes the variant, destructuring pattern, and format arguments. ```rust fn generate_arm( variant: &str, destructure: TokenTree, string: Literal, stream: TokenStream, ) -> DisplayArm { [ TokenTree::Ident(Ident::new("Self", Span::call_site())), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new(variant, Span::call_site())), destructure, TokenTree::Punct(Punct::new('=', Spacing::Joint)), TokenTree::Punct(Punct::new('>', Spacing::Joint)), TokenTree::Ident(Ident::new("f", Span::call_site())), TokenTree::Punct(Punct::new('.', Spacing::Joint)), TokenTree::Ident(Ident::new("write_fmt", Span::call_site())), TokenTree::Group(Group::new( Delimiter::Parenthesis, TokenStream::from_iter([ TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new("core", Span::call_site())), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Punct(Punct::new(':', Spacing::Joint)), TokenTree::Ident(Ident::new("format_args", Span::call_site())), TokenTree::Punct(Punct::new('!', Spacing::Joint)), TokenTree::Group(Group::new( Delimiter::Parenthesis, [TokenTree::Literal(string)] .into_iter() .chain(stream) .collect(), )), ]), )), ] } ``` -------------------------------- ### Implement Display for Enum with displaystr Source: https://docs.rs/displaystr Use the `#[display]` attribute macro on enums to automatically implement the `core::fmt::Display` trait. Each enum variant can be assigned a format string, optionally referencing its fields. ```rust use displaystr::display; #[display] pub enum DataStoreError { Disconnect(std::io::Error) = "data store disconnected", Redaction(String) = "the data for key `{_0}` is not available", InvalidHeader { expected: String, found: String, } = "invalid header (expected {expected:?}, found {found:?})", Unknown = "unknown data store error", } ``` -------------------------------- ### Display implementation for enum variants Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html This code shows the expanded implementation of the `Display` trait for an enum, generated by the `#[display]` macro. It matches enum variants and formats strings accordingly. ```rust impl ::core::fmt::Display for DataStoreError { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { match self { Self::Disconnect(_0) => { f.write_fmt(format_args!("data store disconnected")) } Self::InvalidHeader { expected, found } => { f.write_fmt(format_args!("invalid header (expected {expected}, found {found})")) } } } } ``` -------------------------------- ### Expanded Display implementation for enum variants Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html This code shows the expanded implementation of the `Display` trait for an enum, generated by the `#[display]` macro. It matches enum variants and formats strings accordingly. ```rust pub enum DataStoreError { Disconnect(std::io::Error), InvalidHeader { expected: String, found: String, }, } impl ::core::fmt::Display for DataStoreError { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { match self { Self::Disconnect(_0) => { f.write_fmt(format_args!("data store disconnected")) } Self::InvalidHeader { expected, found } => { f.write_fmt(format_args!("invalid header (expected {expected}, found {found})")) } } } } ``` -------------------------------- ### Expanded Enum with Multiple Arguments Source: https://docs.rs/displaystr This shows the generated `impl Display` for an enum variant that uses multiple arguments in its format string, including an expression to format a field. ```rust use displaystr::display; pub enum DataStoreError { Redaction(String, Vec), } impl ::core::fmt::Display for DataStoreError { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { match self { Self::Redaction(_0, _1) => f.write_fmt(format_args!( "the data for key `{_0}` is not available, but we recovered: {}", _1.join("+") )), } } } ``` -------------------------------- ### Create CompileError Instance Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Creates a new `CompileError` with a specified span and message. Use this to define compile-time errors. ```rust pub fn new(span: Span, message: impl AsRef) -> Self { Self { span, message: message.as_ref().to_string(), } } ``` -------------------------------- ### Implement Display for Enum with displaystr Source: https://docs.rs/displaystr/latest/displaystr/attr.display.html Use the `#[display]` attribute macro to automatically derive the `Display` trait for an enum. This macro allows custom string formatting for enum variants, including those with data. ```rust use displaystr::display; #[display] pub enum DataStoreError { Disconnect(std::io::Error) = "data store disconnected", InvalidHeader { expected: String, found: String, } = "invalid header (expected {expected:?}, found {found:?})", } ``` ```rust use displaystr::display; pub enum DataStoreError { Disconnect(std::io::Error), InvalidHeader { expected: String, found: String, }, } impl ::core::fmt::Display for DataStoreError { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { match self { Self::Disconnect(_0) => { f.write_fmt(format_args!("data store disconnected")) } Self::InvalidHeader { expected, found } => { f.write_fmt(format_args!("invalid header (expected {expected}, found {found})")) } } } } ``` -------------------------------- ### Parsing Enum Attributes and Keywords Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html This code parses and collects attributes, the 'enum' keyword, and the enum identifier. It handles skipping attributes like '#[foo = bar]' and ensures the 'enum' keyword is correctly identified. ```rust loop { let Some(tt) = ts.next() else { return CompileError::new(Span::call_site(), "expected an `enum` item") .into_iter() .collect(); }; match tt { // Skip all `OuterAttribute` // // #[foo = bar] // ^ TokenTree::Punct(punct) if punct == '#' => { output.extend([TokenTree::Punct(punct)]); // #[foo = bar] // ^^^^^^^^^^^ output.extend(ts.next()); } // Reached enum keyword. End parsing. // // enum Foo { ... } // ^^^^ TokenTree::Ident(ident) if ident.to_string() == "enum" => { output.extend([TokenTree::Ident(ident)]); break; } // ignore any other token e.g. `pub` or `(crate)` tt => { output.extend([tt]); } } } ``` -------------------------------- ### Handle Enum Variant Parsing Errors Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Provides a dummy arm for compilation continuation when an error occurs during enum variant string extraction. Collects compile errors. ```rust arms.extend(generate_arm( &variant_ident.to_string(), destructure, Literal::string(""), TokenStream::new(), )); compile_errors.extend(compile_error); ``` -------------------------------- ### Enum Error Definition with displaydoc and thiserror Source: https://docs.rs/displaystr/latest/displaystr Defines an enum for data store errors using both `thiserror` and `displaydoc`. `displaydoc` automatically generates `Display` implementations from doc comments. ```rust use thiserror::Error; use displaydoc::Display; #[derive(Display, Error, Debug)] pub enum DataStoreError { /// data store disconnected Disconnect(#[source] io::Error), /// the data for key `{0}` is not available Redaction(String), /// invalid header (expected {expected:?}, found {found:?}) InvalidHeader { expected: String, found: String, }, /// unknown data store error Unknown, } ``` -------------------------------- ### Handle Unit Variant with Trailing Comma Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Handles a unit variant followed by a comma, which is considered invalid as it expects a string discriminant. It generates a compile error and a dummy arm for compilation. ```rust Some(TokenTree::Punct(punct)) if punct == ',' => { variant.extend([TokenTree::Punct(punct.clone())]); compile_errors.extend(CompileError::new( variant_ident.span(), "expected this variant to have a string discriminant: `= \"...\"`", )); // DUMMY arm so we compile. so rust-analyzer works better arms.extend(generate_arm( &variant_ident.to_string(), // Foo {} // ^^ TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())), Literal::string(""), TokenStream::new(), )); } ``` -------------------------------- ### Destructuring Tuple Variant Fields Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Generates destructuring bindings (e.g., '_0', '_1') for tuple variant fields. This is used when generating code to access individual fields within a variant. ```rust let destructure = (0..variant_count) .flat_map(|i| { [ TokenTree::Ident(Ident::new(&format!("_{i}"), Span::call_site())), TokenTree::Punct(Punct::new(',', Spacing::Joint)), ] }) .collect(); ``` -------------------------------- ### Handle Unit Variant with No Trailing Comma Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Handles the case where a unit variant is the last one and has no trailing comma. This is also considered invalid as it expects a string discriminant. It generates a compile error and a dummy arm. ```rust None => { compile_errors.extend(CompileError::new( variant_ident.span(), "expected this variant to have a string discriminant: `= \"...\"`", )); // DUMMY arm so we compile. so rust-analyzer works better arms.extend(generate_arm( &variant_ident.to_string(), // Foo {} // ^^ TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())), Literal::string(""), TokenStream::new(), )); break; } ``` -------------------------------- ### Parsing Enum Variant Visibility Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Handles parsing of visibility modifiers like 'pub' and 'pub(crate)' for enum variants. It extracts these modifiers to be included in the generated code. ```rust Some(TokenTree::Ident(ident)) if ident.to_string() == "pub" => { variant.extend(enum_body.next()); match enum_body.peek() { // pub(in crate) // ^^^^^^^^^^^ Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Parenthesis => { variant.extend(enum_body.next()); } _ => () } } ``` -------------------------------- ### Implement IntoIterator for CompileError Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Converts a `CompileError` into an iterator of `TokenTree`s, representing the `compile_error!($message)` macro invocation. This is useful for generating code at compile time. ```rust impl IntoIterator for CompileError { type Item = TokenTree; type IntoIter = std::array::IntoIter; fn into_iter(self) -> Self::IntoIter { [ TokenTree::Ident(Ident::new("compile_error", self.span)), TokenTree::Punct({ let mut punct = Punct::new('!', Spacing::Alone); punct.set_span(self.span); punct }), TokenTree::Group({ let mut group = Group::new(Delimiter::Brace, { TokenStream::from_iter(vec![TokenTree::Literal({ let mut string = Literal::string(&self.message); string.set_span(self.span); string })]) }); group.set_span(self.span); group }), ] .into_iter() } } ``` -------------------------------- ### Parsing Tuple Variant Fields Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Parses the fields of a tuple variant, like '(a, b)' in 'Foo(a, b)'. It counts the number of fields to correctly destructure them later. ```rust Some(TokenTree::Group(fields)) if fields.delimiter() == Delimiter::Parenthesis => { variant.extend([TokenTree::Group(fields.clone())]); // Foo() has 0 variant. Otherwise, start the count at 1 let mut fields = fields.stream().into_iter().peekable(); let is_zero_variants = fields.peek().is_none(); // Let's count how many commas there are between each field // // Foo(bar, baz, quux,) // ^ this one // ^ and this one // ^ but not this one (it is trailing) let mut commas = 0; while let Some(tt) = fields.next() { match tt { TokenTree::Punct(punct) if punct == ',' => { // Only count non-trailing commas if fields.peek().is_some() { commas += 1; } } // ignore any other tokens _ => () } } // Foo() has 0 fields // Foo(bar) has 1 field // Foo(bar,) has 1 field // Foo(bar,baz) has 2 fields let variant_count = if is_zero_variants { 0 } else { 1 + commas }; ``` -------------------------------- ### Generate Enum Variant Arm Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Generates a match arm for an enum variant, extracting a string literal and associated stream of tokens. Used when doc comments are enabled. ```rust arms.extend(generate_arm( &variant_ident.to_string(), destructure, string, stream, )); ``` -------------------------------- ### Extracting Where Clause from Enum Definition Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html This code extracts the 'where' clause from an enum definition. It continues to consume tokens until it encounters the opening brace of the enum body. ```rust let where_clause = match ts.peek() { Some(TokenTree::Ident(ident)) if ident.to_string() == "where" => { let mut where_clause = TokenStream::new(); where_clause.extend(ts.next()); loop { match ts.peek() { Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Brace => break, _ => { where_clause.extend(ts.next()); } } } where_clause } _ => TokenStream::new(), }; ``` -------------------------------- ### Handle Compile Error in Enum Variant Parsing Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html This code arm handles compile errors during enum variant parsing, extending the list of compile errors and generating a dummy arm to ensure compilation proceeds. ```rust Err(compile_error) => { // dummy arm so we just continue compiling arms.extend(generate_arm( &variant_ident.to_string(), destructure, Literal::string(""), TokenStream::new(), )); compile_errors.extend(compile_error); } ``` -------------------------------- ### Parsing Enum Body Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html This snippet parses the main body of the enum definition, which is expected to be enclosed in curly braces. It prepares the stream of tokens within the braces for further processing. ```rust let mut enum_body = match ts.next() { Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Brace => { group.stream().into_iter().peekable() } _ => unreachable!("enum has braces"), }; ``` -------------------------------- ### Enum Error Definition with thiserror Source: https://docs.rs/displaystr/latest/displaystr Defines an enum for data store errors using `thiserror`. Each variant has a custom error message. ```rust use thiserror::Error; #[derive(Error, Debug)] pub enum DataStoreError { #[error("data store disconnected")] Disconnect(#[from] io::Error), #[error("the data for key `{0}` is not available")] Redaction(String), #[error("invalid header (expected {expected:?}, found {found:?})")] InvalidHeader { expected: String, found: String, }, #[error("unknown data store error")] Unknown, } ``` -------------------------------- ### Parse Enum Variant with String Discriminant Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Parses an enum variant that has a string discriminant. It extracts the string, generates documentation comments if enabled, and creates a corresponding arm for the display string generation. ```rust Some(TokenTree::Punct(punct)) if punct == '=' => { // Foo = "foo", // ^^^^^ match extract_string(&mut enum_body) { Ok((string, stream)) => { if generate_doc_comments { variants.extend(doc_comment(&string.to_string())); } // Success. arms.extend(generate_arm( &variant_ident.to_string(), // Foo {} // ^^ TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())), string, stream, )); } Err(compile_error) => { compile_errors.extend(compile_error); // DUMMY arm so we compile. so rust-analyzer works better arms.extend(generate_arm( &variant_ident.to_string(), // Foo {} // ^^ TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())), Literal::string(""), TokenStream::new(), )); } } // Foo = "foo", // ^ match enum_body.peek() { Some(TokenTree::Punct(punct)) if *punct == ',' => { // trailing comma variant.extend(enum_body.next()); } _ => () } } ``` -------------------------------- ### Extracting Generics from Enum Definition Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html This snippet extracts the generic parameters of an enum, including the angle brackets and their contents. It handles cases with and without generics. ```rust let generics = match ts.peek() { // opening '<' // // enum Foo { ... } // ^ Some(TokenTree::Punct(punct)) if *punct == '<' => { let mut generics = TokenStream::new(); generics.extend(ts.next()); loop { match ts.next() { // closing '>' // // enum Foo { ... } // ^ Some(TokenTree::Punct(punct)) if punct == '>' => { generics.extend([TokenTree::Punct(punct)]); break; } tt => { generics.extend(tt); } } } generics } _ => TokenStream::new(), }; ``` -------------------------------- ### Parse Struct Variant Fields Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Iterates through the fields of a struct variant, identifying and collecting fields that are followed by a colon, indicating a type annotation. Handles nested types and trailing commas. ```rust loop { let current = fields.next(); match fields.peek() { Some(TokenTree::Punct(punct)) if *punct == ':' && !is_inside_type => { // Self::InvalidHeader { expected, found, } => f.write_fmt(format_args!( ``` ```rust destructure.extend(current); // Self::InvalidHeader { expected, found, } => f.write_fmt(format_args!( ``` ```rust destructure.extend([TokenTree::Punct(Punct::new(',', Spacing::Joint))]); is_inside_type = true; } // foo: Bar, // ^ Some(TokenTree::Punct(punct)) if *punct == ',' && is_inside_type => { is_inside_type = false; } // ignore any other tokens like `#[doc = "..."]` or `pub(crate)` Some(_) => (), // Reached end of the struct variant's fields None => break, } } ``` -------------------------------- ### Parsing Enum Variant Attributes Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Parses attributes like #[foo = bar] preceding an enum variant. These attributes are collected before the variant's main definition. ```rust Some(TokenTree::Punct(punct)) if *punct == '#' => { // #[foo = bar] // ^ variants.extend(enum_body.next()); // #[foo = bar] // ^^^^^^^^^^^ variants.extend(enum_body.next()); } ``` -------------------------------- ### Extract String Literal from Token Stream Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Extracts a string literal from a token stream, handling both direct literals and parenthesized expressions. Used when parsing string discriminants for enum variants. ```rust fn extract_string( ts: &mut std::iter::Peekable, ) -> Result<(Literal, TokenStream), CompileError> { let next = ts.next(); match next { Some(TokenTree::Literal(string)) => { // Success. Ok((string, TokenStream::new())) } Some(TokenTree::Group(group)) if group.delimiter() == Delimiter::Parenthesis => { let mut stream = group.stream().into_iter(); match stream.next() { Some(TokenTree::Literal(string)) => Ok((string, stream.collect())), Some(tt) => Err(CompileError::new(tt.span(), "expected string literal")), None => Err(CompileError::new(group.span(), "expected string literal")), } } Some(tt) => Err(CompileError::new(tt.span(), "expected string literal")), None => unreachable!("`=` is always followed by an expression"), } } ``` -------------------------------- ### Parsing Enum Variant Identifier Source: https://docs.rs/displaystr/latest/src/displaystr/lib.rs.html Extracts the identifier for an enum variant, such as 'Foo' in 'Foo {}' or 'Foo(a, b)'. This identifier is crucial for constructing the variant's representation. ```rust let variant_ident = match enum_body.next() { Some(TokenTree::Ident(ident)) => { variant.extend([TokenTree::Ident(ident.clone())]); ident } _ => unreachable!("identifier must appear in this position"), }; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.