diff --git a/forc-plugins/forc-doc/src/doc/descriptor.rs b/forc-plugins/forc-doc/src/doc/descriptor.rs index a7a88148390..43ef6f10c2d 100644 --- a/forc-plugins/forc-doc/src/doc/descriptor.rs +++ b/forc-plugins/forc-doc/src/doc/descriptor.rs @@ -73,7 +73,7 @@ impl Descriptor { attrs_opt: attrs_opt.clone(), item_context: ItemContext { context_opt: context, - impl_traits: None, + ..Default::default() }, }, raw_attributes: attrs_opt, @@ -110,7 +110,7 @@ impl Descriptor { attrs_opt: attrs_opt.clone(), item_context: ItemContext { context_opt: context, - impl_traits: None, + ..Default::default() }, }, raw_attributes: attrs_opt, @@ -158,7 +158,7 @@ impl Descriptor { attrs_opt: attrs_opt.clone(), item_context: ItemContext { context_opt: context, - impl_traits: None, + ..Default::default() }, }, raw_attributes: attrs_opt, @@ -200,7 +200,7 @@ impl Descriptor { attrs_opt: attrs_opt.clone(), item_context: ItemContext { context_opt: context, - impl_traits: None, + ..Default::default() }, }, raw_attributes: attrs_opt, @@ -235,7 +235,7 @@ impl Descriptor { attrs_opt: attrs_opt.clone(), item_context: ItemContext { context_opt: context, - impl_traits: None, + ..Default::default() }, }, raw_attributes: attrs_opt, @@ -267,7 +267,7 @@ impl Descriptor { attrs_opt: attrs_opt.clone(), item_context: ItemContext { context_opt: None, - impl_traits: None, + ..Default::default() }, }, raw_attributes: attrs_opt, @@ -300,7 +300,7 @@ impl Descriptor { attrs_opt: attrs_opt.clone(), item_context: ItemContext { context_opt: None, - impl_traits: None, + ..Default::default() }, }, raw_attributes: attrs_opt, diff --git a/forc-plugins/forc-doc/src/doc/mod.rs b/forc-plugins/forc-doc/src/doc/mod.rs index 0a21967f90e..801e7bfed96 100644 --- a/forc-plugins/forc-doc/src/doc/mod.rs +++ b/forc-plugins/forc-doc/src/doc/mod.rs @@ -76,16 +76,17 @@ impl Documentation { // currently this compares the spans as str, but this needs to change // to compare the actual types for doc in docs.iter_mut() { - let mut impl_vec: Vec = Vec::new(); + let mut impl_trait_vec: Vec = Vec::new(); + let mut inherent_impl_vec: Vec = Vec::new(); match doc.item_body.ty_decl { TyDecl::StructDecl(ref decl) => { for (impl_trait, module_info) in impl_traits.iter_mut() { let struct_decl = engines.de().get_struct(&decl.decl_id); - if struct_decl.name().as_str() == impl_trait.implementing_for.span.as_str() - && struct_decl.name().as_str() - != impl_trait.trait_name.suffix.span().as_str() - { + let struct_name = struct_decl.name().as_str(); + + // Check if this implementation is for this struct. + if struct_name == impl_trait.implementing_for.span.as_str() { let module_info_override = if let Some(decl_module_info) = trait_decls.get(&impl_trait.trait_name.suffix) { @@ -97,19 +98,33 @@ impl Documentation { None }; - impl_vec.push(DocImplTrait { - impl_for_module: module_info.clone(), - impl_trait: impl_trait.clone(), - module_info_override, - }); + if struct_name == impl_trait.trait_name.suffix.span().as_str() { + // If the trait name is the same as the struct name, it's an inherent implementation. + inherent_impl_vec.push(DocImplTrait { + impl_for_module: module_info.clone(), + impl_trait: impl_trait.clone(), + module_info_override: None, + }); + } else { + // Otherwise, it's an implementation for a trait. + impl_trait_vec.push(DocImplTrait { + impl_for_module: module_info.clone(), + impl_trait: impl_trait.clone(), + module_info_override, + }); + } } } } _ => continue, } - if !impl_vec.is_empty() { - doc.item_body.item_context.impl_traits = Some(impl_vec); + if !impl_trait_vec.is_empty() { + doc.item_body.item_context.impl_traits = Some(impl_trait_vec.clone()); + } + + if !inherent_impl_vec.is_empty() { + doc.item_body.item_context.inherent_impls = Some(inherent_impl_vec); } } diff --git a/forc-plugins/forc-doc/src/render/item/context.rs b/forc-plugins/forc-doc/src/render/item/context.rs index 98ef575fc54..f0aff1b2ce1 100644 --- a/forc-plugins/forc-doc/src/render/item/context.rs +++ b/forc-plugins/forc-doc/src/render/item/context.rs @@ -264,22 +264,25 @@ impl Renderable for Context { }) } } + #[derive(Debug, Clone)] pub struct DocImplTrait { pub impl_for_module: ModuleInfo, pub impl_trait: TyImplTrait, pub module_info_override: Option>, } -#[derive(Clone, Debug)] + +#[derive(Clone, Debug, Default)] /// The context section of an item that appears in the page [ItemBody]. pub struct ItemContext { /// [Context] can be fields on a struct, variants of an enum, etc. pub context_opt: Option, + // The implementations for this type. + pub inherent_impls: Option>, /// The traits implemented for this type. pub impl_traits: Option>, - // TODO: All other Implementation types, eg - // implementations on foreign types, method implementations, etc. } + impl ItemContext { pub fn to_doclinks(&self) -> DocLinks { let mut links: BTreeMap> = BTreeMap::new(); @@ -379,26 +382,48 @@ impl Renderable for ItemContext { let impl_traits = match self.impl_traits { Some(impl_traits) => { - let mut impl_vec: Vec<_> = Vec::with_capacity(impl_traits.len()); + let mut impl_trait_vec: Vec<_> = Vec::with_capacity(impl_traits.len()); for impl_trait in impl_traits { - impl_vec.push(impl_trait.render(render_plan.clone())?); + impl_trait_vec.push(impl_trait.render(render_plan.clone())?); } - Some(impl_vec) + impl_trait_vec } - None => None, + None => vec![], + }; + + let inherent_impls = match self.inherent_impls { + Some(inherent_impls) => { + let mut inherent_impl_vec: Vec<_> = Vec::with_capacity(inherent_impls.len()); + for inherent_impl in inherent_impls { + inherent_impl_vec.push(inherent_impl.render(render_plan.clone())?); + } + inherent_impl_vec + } + None => vec![], }; Ok(box_html! { @ if let Some(context) = context_opt { : Raw(context); } - @ if impl_traits.is_some() { + @ if !inherent_impls.is_empty() { + h2(id="inherent-implementations", class="small-section-header") { + : "Implementations"; + a(href=format!("{IDENTITY}inherent-implementations"), class="anchor"); + } + div(id="inherent-implementations-list") { + @ for inherent_impl in inherent_impls { + : inherent_impl; + } + } + } + @ if !impl_traits.is_empty() { h2(id="trait-implementations", class="small-section-header") { : "Trait Implementations"; a(href=format!("{IDENTITY}trait-implementations"), class="anchor"); } div(id="trait-implementations-list") { - @ for impl_trait in impl_traits.unwrap() { + @ for impl_trait in impl_traits { : impl_trait; } } @@ -414,6 +439,7 @@ impl Renderable for DocImplTrait { implementing_for, .. } = self.impl_trait; + let is_inherent = trait_name.suffix.as_str() == implementing_for.span.as_str(); let impl_for_module = self.impl_for_module; let no_deps = render_plan.no_deps; let is_external_item = if let Some(project_root) = trait_name.prefixes.first() { @@ -453,8 +479,10 @@ impl Renderable for DocImplTrait { : trait_name.suffix.as_str(); } } - : " for "; - : implementing_for.span.as_str(); + @ if !is_inherent { + : " for "; + : implementing_for.span.as_str(); + } } } } @@ -463,7 +491,7 @@ impl Renderable for DocImplTrait { Ok(box_html! { // check if the implementation has methods @ if !rendered_items.is_empty() { - details(class="swaydoc-toggle implementors-toggle") { + details(class="swaydoc-toggle implementors-toggle", open) { summary { : Raw(impl_for); } @@ -582,7 +610,7 @@ impl Renderable for TyTraitItem { summary { : Raw(impl_list); } - div(class="doc-block") { + div(class="docblock") { : Raw(attributes); } } diff --git a/forc-plugins/forc-doc/src/static.files/ayu.css b/forc-plugins/forc-doc/src/static.files/ayu.css index 47703d1a9b4..00a5e6ec819 100644 --- a/forc-plugins/forc-doc/src/static.files/ayu.css +++ b/forc-plugins/forc-doc/src/static.files/ayu.css @@ -1,8 +1,8 @@ :root { - --main-background-color: #0f1419; + --main-background-color: #262e37; --main-color: #c5c5c5; --settings-input-color: #ffb454; - --sidebar-background-color: #14191f; + --sidebar-background-color: #161f25; --sidebar-background-color-hover: rgba(70, 70, 70, 0.33); --code-block-background-color: #191f26; --scrollbar-track-background-color: transparent; diff --git a/forc-plugins/forc-doc/src/static.files/swaydoc.css b/forc-plugins/forc-doc/src/static.files/swaydoc.css index dc3abdbbe7e..456264486ae 100644 --- a/forc-plugins/forc-doc/src/static.files/swaydoc.css +++ b/forc-plugins/forc-doc/src/static.files/swaydoc.css @@ -152,7 +152,7 @@ h2, border-bottom: 1px solid var(--headings-border-bottom-color); } h3.code-header { - font-size: 1em; + font-size: 1.125rem; font-weight: 600; } h4.code-header { @@ -604,18 +604,14 @@ h2.location a { .top-doc .docblock h6 { font-size: 1rem; } -.docblock h5 { - font-size: 1rem; -} -.docblock h6 { - font-size: 0.875rem; -} .docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5, .docblock h6 { + font-size: 1.125rem; + color: var(--main-color); border-bottom-color: var(--headings-border-bottom-color); } .docblock { diff --git a/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs b/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs index 7aacbc7bd52..00f01c8df17 100644 --- a/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs +++ b/forc-plugins/forc-doc/src/tests/expects/impl_trait/mod.rs @@ -38,8 +38,8 @@ fn test_impl_traits_default() { &doc_path, project_name, &expect![[ - r##"Bar in bar - Sway
pub struct Bar {}

Trait Implementations

fn foo()

something more about foo();

-

fn add(self, other: Self) -> Self

fn subtract(self, other: Self) -> Self

"## + r##"Bar in bar - Sway
pub struct Bar {}

Implementations

fn foo_bar()

Trait Implementations

fn foo()

something more about foo();

+

fn add(self, other: Self) -> Self

fn subtract(self, other: Self) -> Self

"## ]], ); assert_search_js( @@ -121,8 +121,8 @@ fn test_impl_traits_no_deps() { &doc_path, project_name, &expect![[ - r##"Bar in bar - Sway
pub struct Bar {}

Trait Implementations

fn foo()

something more about foo();

-

fn add(self, other: Self) -> Self

fn subtract(self, other: Self) -> Self

"## + r##"Bar in bar - Sway
pub struct Bar {}

Implementations

fn foo_bar()

Trait Implementations

fn foo()

something more about foo();

+

fn add(self, other: Self) -> Self

fn subtract(self, other: Self) -> Self

"## ]], ); assert_search_js(