diff options
author | Jeremy Banks <_@jeremy.ca> | 2019-05-11 10:52:18 -0400 |
---|---|---|
committer | Jeremy Banks <_@jeremy.ca> | 2019-05-11 11:07:51 -0400 |
commit | c41add741dbe4a97fb04d5236ba91f87ca567b4e (patch) | |
tree | 5bc1079fa5173d1a4ece44f78119cc99f64f1e85 /src | |
parent | 320efb2ae98e815be196609d7ba600a78cf6727f (diff) | |
download | remain-c41add741dbe4a97fb04d5236ba91f87ca567b4e.tar.gz |
Add support for sorting named struct fields.
Diffstat (limited to 'src')
-rw-r--r-- | src/check.rs | 17 | ||||
-rw-r--r-- | src/emit.rs | 5 | ||||
-rw-r--r-- | src/lib.rs | 6 | ||||
-rw-r--r-- | src/parse.rs | 14 |
4 files changed, 34 insertions, 8 deletions
diff --git a/src/check.rs b/src/check.rs index 281c052..1b50442 100644 --- a/src/check.rs +++ b/src/check.rs @@ -1,5 +1,5 @@ use syn::{Arm, Ident, Result, Variant}; -use syn::{Error, Pat, PatIdent}; +use syn::{Error, Field, Fields, Pat, PatIdent}; use crate::compare::Path; use crate::format; @@ -8,6 +8,13 @@ use crate::parse::Input::{self, *}; pub fn sorted(input: Input) -> Result<()> { let paths = match input { Enum(item) => collect_paths(item.variants)?, + Struct(item) => { + if let Fields::Named(fields) = item.fields { + collect_paths(fields.named)? + } else { + unreachable!("must be named field") + } + } Match(expr) | Let(expr) => collect_paths(expr.arms)?, }; @@ -44,6 +51,14 @@ impl IntoPath for Variant { } } +impl IntoPath for Field { + fn into_path(self) -> Result<Path> { + Ok(Path { + segments: vec![self.ident.expect("must be named field")], + }) + } +} + impl IntoPath for Arm { fn into_path(self) -> Result<Path> { // Sort by just the first pat. diff --git a/src/emit.rs b/src/emit.rs index b98ad1d..d1ddda8 100644 --- a/src/emit.rs +++ b/src/emit.rs @@ -7,6 +7,7 @@ use syn::Error; pub enum Kind { Enum, Match, + Struct, Let, } @@ -21,7 +22,7 @@ pub fn emit(err: Error, kind: Kind, original: TokenStream) -> TokenStream { let original = proc_macro2::TokenStream::from(original); let expanded = match kind { - Kind::Enum | Kind::Let => quote!(#err #original), + Kind::Enum | Kind::Let | Kind::Struct => quote!(#err #original), Kind::Match => quote!({ #err #original }), }; @@ -32,7 +33,7 @@ pub fn emit(err: Error, kind: Kind, original: TokenStream) -> TokenStream { // https://github.com/rust-lang/rust/issues/43081 fn probably_has_spans(kind: Kind) -> bool { match kind { - Kind::Enum => true, + Kind::Enum | Kind::Struct => true, Kind::Match | Kind::Let => false, } } @@ -4,8 +4,8 @@ //! //! # Syntax //! -//! Place a `#[remain::sorted]` attribute on enums, on match-expressions, or on -//! let-statements whose value is a match-expression. +//! Place a `#[remain::sorted]` attribute on enums, on named structs, on +//! match-expressions, or on let-statements whose value is a match-expression. //! //! Alternatively, import as `use remain::sorted;` and use `#[sorted]` as the //! attribute. @@ -76,7 +76,7 @@ //! # fn main() {} //! ``` //! -//! If an enum variant or match arm is inserted out of order, +//! If an enum variant, struct field, or match arm is inserted out of order,\ //! //! ```diff //! NetDeviceNew(virtio::NetError), diff --git a/src/parse.rs b/src/parse.rs index 77fd4bc..98b8c86 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,6 +1,6 @@ use proc_macro2::Span; use syn::parse::{Parse, ParseStream}; -use syn::{Attribute, Error, Expr, Result, Stmt, Token, Visibility}; +use syn::{Attribute, Error, Expr, Fields, Result, Stmt, Token, Visibility}; use crate::emit::Kind; @@ -15,6 +15,7 @@ impl Parse for Nothing { pub enum Input { Enum(syn::ItemEnum), Match(syn::ExprMatch), + Struct(syn::ItemStruct), Let(syn::ExprMatch), } @@ -23,6 +24,7 @@ impl Input { match self { Input::Enum(_) => Kind::Enum, Input::Match(_) => Kind::Match, + Input::Struct(_) => Kind::Struct, Input::Let(_) => Kind::Let, } } @@ -61,6 +63,14 @@ impl Parse for Input { if ahead.peek(Token![enum]) { return input.parse().map(Input::Enum); } + if ahead.peek(Token![struct]) { + let input = input.parse().map(Input::Struct)?; + if let Input::Struct(ref item) = input { + if let Fields::Named(_) = item.fields { + return Ok(input); + } + } + } Err(unexpected()) } @@ -68,6 +78,6 @@ impl Parse for Input { fn unexpected() -> Error { let span = Span::call_site(); - let msg = "expected enum or match expression"; + let msg = "expected enum, named struct, or match expression"; Error::new(span, msg) } |