Make Ord
, PartialOrd
opt-out in newtype_index
Also remove `step` impl if `ORD_IMPL = off`
This commit is contained in:
parent
4566094913
commit
c08a9a4f1d
1 changed files with 46 additions and 24 deletions
|
@ -10,6 +10,7 @@ mod kw {
|
||||||
syn::custom_keyword!(MAX);
|
syn::custom_keyword!(MAX);
|
||||||
syn::custom_keyword!(ENCODABLE);
|
syn::custom_keyword!(ENCODABLE);
|
||||||
syn::custom_keyword!(custom);
|
syn::custom_keyword!(custom);
|
||||||
|
syn::custom_keyword!(ORD_IMPL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -42,6 +43,7 @@ impl Parse for Newtype {
|
||||||
let mut max = None;
|
let mut max = None;
|
||||||
let mut consts = Vec::new();
|
let mut consts = Vec::new();
|
||||||
let mut encodable = true;
|
let mut encodable = true;
|
||||||
|
let mut ord = true;
|
||||||
|
|
||||||
// Parse an optional trailing comma
|
// Parse an optional trailing comma
|
||||||
let try_comma = || -> Result<()> {
|
let try_comma = || -> Result<()> {
|
||||||
|
@ -99,13 +101,20 @@ impl Parse for Newtype {
|
||||||
encodable = false;
|
encodable = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if body.lookahead1().peek(kw::ORD_IMPL) {
|
||||||
|
body.parse::<kw::ORD_IMPL>()?;
|
||||||
|
body.parse::<Token![=]>()?;
|
||||||
|
body.parse::<kw::custom>()?;
|
||||||
|
ord = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// We've parsed everything that the user provided, so we're done
|
// We've parsed everything that the user provided, so we're done
|
||||||
if body.is_empty() {
|
if body.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, we are parsng a user-defined constant
|
// Otherwise, we are parsing a user-defined constant
|
||||||
let const_attrs = body.call(Attribute::parse_outer)?;
|
let const_attrs = body.call(Attribute::parse_outer)?;
|
||||||
body.parse::<Token![const]>()?;
|
body.parse::<Token![const]>()?;
|
||||||
let const_name: Ident = body.parse()?;
|
let const_name: Ident = body.parse()?;
|
||||||
|
@ -137,6 +146,40 @@ impl Parse for Newtype {
|
||||||
quote! {}
|
quote! {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if ord {
|
||||||
|
derive_paths.push(parse_quote!(Ord));
|
||||||
|
derive_paths.push(parse_quote!(PartialOrd));
|
||||||
|
}
|
||||||
|
|
||||||
|
let step = if ord {
|
||||||
|
quote! {
|
||||||
|
impl ::std::iter::Step for #name {
|
||||||
|
#[inline]
|
||||||
|
fn steps_between(start: &Self, end: &Self) -> Option<usize> {
|
||||||
|
<usize as ::std::iter::Step>::steps_between(
|
||||||
|
&Self::index(*start),
|
||||||
|
&Self::index(*end),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn forward_checked(start: Self, u: usize) -> Option<Self> {
|
||||||
|
Self::index(start).checked_add(u).map(Self::from_usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn backward_checked(start: Self, u: usize) -> Option<Self> {
|
||||||
|
Self::index(start).checked_sub(u).map(Self::from_usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safety: The implementation of `Step` upholds all invariants.
|
||||||
|
unsafe impl ::std::iter::TrustedStep for #name {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {}
|
||||||
|
};
|
||||||
|
|
||||||
let debug_impl = match debug_format {
|
let debug_impl = match debug_format {
|
||||||
DebugFormat::Custom => quote! {},
|
DebugFormat::Custom => quote! {},
|
||||||
DebugFormat::Format(format) => {
|
DebugFormat::Format(format) => {
|
||||||
|
@ -152,7 +195,7 @@ impl Parse for Newtype {
|
||||||
|
|
||||||
Ok(Self(quote! {
|
Ok(Self(quote! {
|
||||||
#(#attrs)*
|
#(#attrs)*
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, #(#derive_paths),*)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, #(#derive_paths),*)]
|
||||||
#[rustc_layout_scalar_valid_range_end(#max)]
|
#[rustc_layout_scalar_valid_range_end(#max)]
|
||||||
#vis struct #name {
|
#vis struct #name {
|
||||||
private: u32,
|
private: u32,
|
||||||
|
@ -247,28 +290,7 @@ impl Parse for Newtype {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::iter::Step for #name {
|
#step
|
||||||
#[inline]
|
|
||||||
fn steps_between(start: &Self, end: &Self) -> Option<usize> {
|
|
||||||
<usize as ::std::iter::Step>::steps_between(
|
|
||||||
&Self::index(*start),
|
|
||||||
&Self::index(*end),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn forward_checked(start: Self, u: usize) -> Option<Self> {
|
|
||||||
Self::index(start).checked_add(u).map(Self::from_usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn backward_checked(start: Self, u: usize) -> Option<Self> {
|
|
||||||
Self::index(start).checked_sub(u).map(Self::from_usize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Safety: The implementation of `Step` upholds all invariants.
|
|
||||||
unsafe impl ::std::iter::TrustedStep for #name {}
|
|
||||||
|
|
||||||
impl From<#name> for u32 {
|
impl From<#name> for u32 {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue