Skip to content

Commit

Permalink
Improve docs feature (#116)
Browse files Browse the repository at this point in the history
* Improve doc parsing, attempt to prevent escaped chars

* parse_quote lit

* Test for docs attr

* Fix docs attr stripping

* Docs feature disabled, don't capture docs via inline fn

* Fix docs feature

* Missing feature attribute

* Fmt

* Move comment on docs fn

* Fix UI test

* Docs feature not enabled by default
  • Loading branch information
ascjones authored Jul 22, 2021
1 parent b4c7fe9 commit eb28e12
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ derive_more = { version = "0.99.1", default-features = false, features = ["from"
scale = { package = "parity-scale-codec", version = "2", default-features = false, features = ["derive"] }

[features]
default = ["std", "docs"]
default = ["std"]
std = [
"bitvec/std",
"scale/std",
Expand Down
20 changes: 8 additions & 12 deletions derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,19 +306,20 @@ fn generate_variant_type(data_enum: &DataEnum, scale_info: &Ident) -> TokenStrea
}
}

#[cfg(feature = "docs")]
fn generate_docs(attrs: &[syn::Attribute]) -> Option<TokenStream2> {
let docs = attrs
.iter()
.filter_map(|attr| {
if let Ok(syn::Meta::NameValue(meta)) = attr.parse_meta() {
if meta.path.get_ident().map_or(false, |ident| ident == "doc") {
let lit = &meta.lit;
let doc_lit = quote!(#lit).to_string();
let trimmed_doc_lit =
doc_lit.trim_start_matches(r#"" "#).trim_end_matches('"');
let lit: syn::Lit = parse_quote!(#trimmed_doc_lit);
Some(lit)
if let syn::Lit::Str(lit) = &meta.lit {
let lit_value = lit.value();
let stripped = lit_value.strip_prefix(' ').unwrap_or(&lit_value);
let lit: syn::Lit = parse_quote!(#stripped);
Some(lit)
} else {
None
}
} else {
None
}
Expand All @@ -332,8 +333,3 @@ fn generate_docs(attrs: &[syn::Attribute]) -> Option<TokenStream2> {
.docs(&[ #( #docs ),* ])
})
}

#[cfg(not(feature = "docs"))]
fn generate_docs(_: &[syn::Attribute]) -> Option<TokenStream2> {
None
}
24 changes: 24 additions & 0 deletions src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,19 @@ impl<S> TypeBuilder<S> {
self
}

#[cfg(feature = "docs")]
/// Set the type documentation
pub fn docs(mut self, docs: &[&'static str]) -> Self {
self.docs = docs.to_vec();
self
}

#[cfg(not(feature = "docs"))]
#[inline]
/// Doc capture is not enabled via the "docs" feature so this is a no-op.
pub fn docs(self, _docs: &'static [&'static str]) -> Self {
self
}
}

/// A fields builder has no fields (e.g. a unit struct)
Expand Down Expand Up @@ -400,6 +408,7 @@ impl<N, T> FieldBuilder<N, T> {
}
}

#[cfg(feature = "docs")]
/// Initialize the documentation of a field (optional).
pub fn docs(self, docs: &'static [&'static str]) -> FieldBuilder<N, T> {
FieldBuilder {
Expand All @@ -410,6 +419,13 @@ impl<N, T> FieldBuilder<N, T> {
marker: PhantomData,
}
}

#[cfg(not(feature = "docs"))]
#[inline]
/// Doc capture is not enabled via the "docs" feature so this is a no-op.
pub fn docs(self, _docs: &'static [&'static str]) -> FieldBuilder<N, T> {
self
}
}

impl<N> FieldBuilder<N, field_state::TypeAssigned> {
Expand Down Expand Up @@ -518,11 +534,19 @@ impl<S> VariantBuilder<S> {
self
}

#[cfg(feature = "docs")]
/// Initialize the variant's documentation.
pub fn docs(mut self, docs: &[&'static str]) -> Self {
self.docs = docs.to_vec();
self
}

#[cfg(not(feature = "docs"))]
#[inline]
/// Doc capture is not enabled via the "docs" feature so this is a no-op.
pub fn docs(self, _docs: &[&'static str]) -> Self {
self
}
}

impl VariantBuilder<variant_state::IndexAssigned> {
Expand Down
15 changes: 15 additions & 0 deletions test_suite/tests/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,21 @@ fn skip_type_params_with_defaults() {
assert_type!(SkipAllTypeParamsWithDefaults<NoScaleInfoImpl, NoScaleInfoImpl>, ty);
}

#[test]
fn docs_attr() {
#[allow(unused)]
#[derive(TypeInfo)]
#[doc = "Docs attr"]
pub struct S;

let ty = Type::builder()
.path(Path::new("S", "derive"))
.docs(&["Docs attr"])
.composite(Fields::unit());

assert_type!(S, ty);
}

#[rustversion::nightly]
#[test]
fn ui_tests() {
Expand Down
9 changes: 8 additions & 1 deletion test_suite/tests/ui/fail_missing_derive.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,11 @@ error[E0277]: the trait bound `PawType<u16>: TypeInfo` is not satisfied
17 | assert_type_info::<Cat<bool, u8, u16>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `TypeInfo` is not implemented for `PawType<u16>`
|
= note: required because of the requirements on the impl of `TypeInfo` for `Cat<bool, u8, u16>`
note: required because of the requirements on the impl of `TypeInfo` for `Cat<bool, u8, u16>`
--> $DIR/fail_missing_derive.rs:7:10
|
7 | #[derive(TypeInfo)]
| ^^^^^^^^
8 | struct Cat<Tail, Ear, Paw> {
| ^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `TypeInfo` (in Nightly builds, run with -Z macro-backtrace for more info)

0 comments on commit eb28e12

Please sign in to comment.