-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Handle more SCALE attributes: skip, index (#44)
* Parameterize CompactForm String for optional SCALE impl By default, parity-scale-codec does not provide Encode/Decode impls for an owned String. This is only provided under the "full" feature which is not used by the substrate runtime, because it should not be used for consensus critical code. So in order for the CompactForm to be integrated into the substrate runtime, or wherever the "full" feature cannot be used, then we must parameterize the `String` type so that it can be both an `&'static str` on the runtime side where it is encoded, and a `String` in client/consuming code where it is decoded. * Fix no-std compilation * Obey the fmt * Introduce String trait for Form * Rename "Compact" to "Frozen" (and associated fallout) Add a `compact` member to `Field` to indicate it is `scale_codec::Compact` * Docs cleanup and more renames * Cleanup * More cleanup * obey the fmt * Add a `compact` flag to `Field` to indicate that this type is to be encoded/decoded as a SCALE Compact type * Clippy warnings * Acommodate older clippy * Derive (scale) compact fields * Use utils from parity-scale-codec-derive Handle `codec(skip)` and `codec(index = $int)` attributes * fmt * Attempt to fix CI * FIx CI take 2 * Use is_compact from utils Ensure we're working with an outer attribute * Fn is enough * Doc tweaks * Add tests for enums * Add test for indexed enum * Oops * Update derive/src/utils.rs Co-authored-by: Andrew Jones <[email protected]> * Review feedback Better error message Remove redundant tests Test more enum cases to document index/discriminant interaction * fmt * Better error message, clearer bad syntax trubuild-test Co-authored-by: Andrew Jones <[email protected]>
- Loading branch information
Showing
8 changed files
with
292 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Copyright 2019-2021 Parity Technologies (UK) Ltd. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
//! Utility methods to work with `SCALE` attributes relevant for the `TypeInfo` derive.. | ||
//! | ||
//! NOTE: The code here is copied verbatim from `parity-scale-codec-derive`. | ||
|
||
use proc_macro2::TokenStream; | ||
use quote::quote; | ||
use syn::{ | ||
spanned::Spanned, | ||
AttrStyle, | ||
Attribute, | ||
Lit, | ||
Meta, | ||
NestedMeta, | ||
Variant, | ||
}; | ||
|
||
/// Look for a `#[codec(index = $int)]` attribute on a variant. If no attribute | ||
/// is found, fall back to the discriminant or just the variant index. | ||
pub fn variant_index(v: &Variant, i: usize) -> TokenStream { | ||
// first look for an attribute | ||
let index = find_meta_item(v.attrs.iter(), |meta| { | ||
if let NestedMeta::Meta(Meta::NameValue(ref nv)) = meta { | ||
if nv.path.is_ident("index") { | ||
if let Lit::Int(ref v) = nv.lit { | ||
let byte = v | ||
.base10_parse::<u8>() | ||
.expect("Internal error. `#[codec(index = …)]` attribute syntax must be checked in `parity-scale-codec`. This is a bug."); | ||
return Some(byte) | ||
} | ||
} | ||
} | ||
|
||
None | ||
}); | ||
|
||
// then fallback to discriminant or just index | ||
index.map(|i| quote! { #i }).unwrap_or_else(|| { | ||
v.discriminant | ||
.as_ref() | ||
.map(|&(_, ref expr)| quote! { #expr }) | ||
.unwrap_or_else(|| quote! { #i }) | ||
}) | ||
} | ||
|
||
/// Look for a `#[codec(compact)]` outer attribute on the given `Field`. | ||
pub fn is_compact(field: &syn::Field) -> bool { | ||
let outer_attrs = field | ||
.attrs | ||
.iter() | ||
.filter(|attr| attr.style == AttrStyle::Outer); | ||
find_meta_item(outer_attrs, |meta| { | ||
if let NestedMeta::Meta(Meta::Path(ref path)) = meta { | ||
if path.is_ident("compact") { | ||
return Some(()) | ||
} | ||
} | ||
|
||
None | ||
}) | ||
.is_some() | ||
} | ||
|
||
/// Look for a `#[codec(skip)]` in the given attributes. | ||
pub fn should_skip(attrs: &[Attribute]) -> bool { | ||
find_meta_item(attrs.iter(), |meta| { | ||
if let NestedMeta::Meta(Meta::Path(ref path)) = meta { | ||
if path.is_ident("skip") { | ||
return Some(path.span()) | ||
} | ||
} | ||
|
||
None | ||
}) | ||
.is_some() | ||
} | ||
|
||
fn find_meta_item<'a, F, R, I>(itr: I, pred: F) -> Option<R> | ||
where | ||
F: Fn(&NestedMeta) -> Option<R> + Clone, | ||
I: Iterator<Item = &'a Attribute>, | ||
{ | ||
itr.filter_map(|attr| { | ||
if attr.path.is_ident("codec") { | ||
if let Meta::List(ref meta_list) = attr | ||
.parse_meta() | ||
.expect("scale-info: Bad index in `#[codec(index = …)]`, see `parity-scale-codec` error") | ||
{ | ||
return meta_list.nested.iter().filter_map(pred.clone()).next() | ||
} | ||
} | ||
|
||
None | ||
}) | ||
.next() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.