//! The document model type AstId = int; type Doc_ = { pages: ~[Page] }; impl Doc_ : cmp::Eq { pure fn eq(other: &Doc_) -> bool { self.pages == (*other).pages } pure fn ne(other: &Doc_) -> bool { !self.eq(other) } } enum Doc { Doc_(Doc_) } impl Doc : cmp::Eq { pure fn eq(other: &Doc) -> bool { *self == *(*other) } pure fn ne(other: &Doc) -> bool { *self != *(*other) } } enum Page { CratePage(CrateDoc), ItemPage(ItemTag) } impl Page : cmp::Eq { pure fn eq(other: &Page) -> bool { match self { CratePage(e0a) => { match (*other) { CratePage(e0b) => e0a == e0b, _ => false } } ItemPage(e0a) => { match (*other) { ItemPage(e0b) => e0a == e0b, _ => false } } } } pure fn ne(other: &Page) -> bool { !self.eq(other) } } enum Implementation { Required, Provided, } impl Implementation : cmp::Eq { pure fn eq(other: &Implementation) -> bool { (self as uint) == ((*other) as uint) } pure fn ne(other: &Implementation) -> bool { !self.eq(other) } } /** * Most rustdocs can be parsed into 'sections' according to their markdown * headers */ type Section = { header: ~str, body: ~str }; impl Section : cmp::Eq { pure fn eq(other: &Section) -> bool { self.header == (*other).header && self.body == (*other).body } pure fn ne(other: &Section) -> bool { !self.eq(other) } } // FIXME (#2596): We currently give topmod the name of the crate. There // would probably be fewer special cases if the crate had its own name // and topmod's name was the empty string. type CrateDoc = { topmod: ModDoc, }; impl CrateDoc : cmp::Eq { pure fn eq(other: &CrateDoc) -> bool { self.topmod == (*other).topmod } pure fn ne(other: &CrateDoc) -> bool { !self.eq(other) } } enum ItemTag { ModTag(ModDoc), NmodTag(NmodDoc), ConstTag(ConstDoc), FnTag(FnDoc), EnumTag(EnumDoc), TraitTag(TraitDoc), ImplTag(ImplDoc), TyTag(TyDoc), StructTag(StructDoc) } impl ItemTag : cmp::Eq { pure fn eq(other: &ItemTag) -> bool { match self { ModTag(e0a) => { match (*other) { ModTag(e0b) => e0a == e0b, _ => false } } NmodTag(e0a) => { match (*other) { NmodTag(e0b) => e0a == e0b, _ => false } } ConstTag(e0a) => { match (*other) { ConstTag(e0b) => e0a == e0b, _ => false } } FnTag(e0a) => { match (*other) { FnTag(e0b) => e0a == e0b, _ => false } } EnumTag(e0a) => { match (*other) { EnumTag(e0b) => e0a == e0b, _ => false } } TraitTag(e0a) => { match (*other) { TraitTag(e0b) => e0a == e0b, _ => false } } ImplTag(e0a) => { match (*other) { ImplTag(e0b) => e0a == e0b, _ => false } } TyTag(e0a) => { match (*other) { TyTag(e0b) => e0a == e0b, _ => false } } StructTag(e0a) => { match (*other) { StructTag(e0b) => e0a == e0b, _ => false } } } } pure fn ne(other: &ItemTag) -> bool { !self.eq(other) } } type ItemDoc = { id: AstId, name: ~str, path: ~[~str], brief: Option<~str>, desc: Option<~str>, sections: ~[Section], // Indicates that this node is a reexport of a different item reexport: bool }; impl ItemDoc : cmp::Eq { pure fn eq(other: &ItemDoc) -> bool { self.id == (*other).id && self.name == (*other).name && self.path == (*other).path && self.brief == (*other).brief && self.desc == (*other).desc && self.sections == (*other).sections && self.reexport == (*other).reexport } pure fn ne(other: &ItemDoc) -> bool { !self.eq(other) } } type SimpleItemDoc = { item: ItemDoc, sig: Option<~str> }; impl SimpleItemDoc : cmp::Eq { pure fn eq(other: &SimpleItemDoc) -> bool { self.item == (*other).item && self.sig == (*other).sig } pure fn ne(other: &SimpleItemDoc) -> bool { !self.eq(other) } } type ModDoc_ = { item: ItemDoc, items: ~[ItemTag], index: Option }; impl ModDoc_ : cmp::Eq { pure fn eq(other: &ModDoc_) -> bool { self.item == (*other).item && self.items == (*other).items && self.index == (*other).index } pure fn ne(other: &ModDoc_) -> bool { !self.eq(other) } } enum ModDoc { ModDoc_(ModDoc_) } impl ModDoc : cmp::Eq { pure fn eq(other: &ModDoc) -> bool { *self == *(*other) } pure fn ne(other: &ModDoc) -> bool { *self != *(*other) } } type NmodDoc = { item: ItemDoc, fns: ~[FnDoc], index: Option }; impl NmodDoc : cmp::Eq { pure fn eq(other: &NmodDoc) -> bool { self.item == (*other).item && self.fns == (*other).fns && self.index == (*other).index } pure fn ne(other: &NmodDoc) -> bool { !self.eq(other) } } type ConstDoc = SimpleItemDoc; type FnDoc = SimpleItemDoc; type EnumDoc = { item: ItemDoc, variants: ~[VariantDoc] }; impl EnumDoc : cmp::Eq { pure fn eq(other: &EnumDoc) -> bool { self.item == (*other).item && self.variants == (*other).variants } pure fn ne(other: &EnumDoc) -> bool { !self.eq(other) } } type VariantDoc = { name: ~str, desc: Option<~str>, sig: Option<~str> }; impl VariantDoc : cmp::Eq { pure fn eq(other: &VariantDoc) -> bool { self.name == (*other).name && self.desc == (*other).desc && self.sig == (*other).sig } pure fn ne(other: &VariantDoc) -> bool { !self.eq(other) } } type TraitDoc = { item: ItemDoc, methods: ~[MethodDoc] }; impl TraitDoc : cmp::Eq { pure fn eq(other: &TraitDoc) -> bool { self.item == (*other).item && self.methods == (*other).methods } pure fn ne(other: &TraitDoc) -> bool { !self.eq(other) } } type MethodDoc = { name: ~str, brief: Option<~str>, desc: Option<~str>, sections: ~[Section], sig: Option<~str>, implementation: Implementation, }; impl MethodDoc : cmp::Eq { pure fn eq(other: &MethodDoc) -> bool { self.name == (*other).name && self.brief == (*other).brief && self.desc == (*other).desc && self.sections == (*other).sections && self.sig == (*other).sig && self.implementation == (*other).implementation } pure fn ne(other: &MethodDoc) -> bool { !self.eq(other) } } type ImplDoc = { item: ItemDoc, trait_types: ~[~str], self_ty: Option<~str>, methods: ~[MethodDoc] }; impl ImplDoc : cmp::Eq { pure fn eq(other: &ImplDoc) -> bool { self.item == (*other).item && self.trait_types == (*other).trait_types && self.self_ty == (*other).self_ty && self.methods == (*other).methods } pure fn ne(other: &ImplDoc) -> bool { !self.eq(other) } } type TyDoc = SimpleItemDoc; type StructDoc = { item: ItemDoc, fields: ~[~str], sig: Option<~str> }; impl StructDoc : cmp::Eq { pure fn eq(other: &StructDoc) -> bool { return self.item == other.item && self.fields == other.fields && self.sig == other.sig; } pure fn ne(other: &StructDoc) -> bool { !self.eq(other) } } type Index = { entries: ~[IndexEntry] }; impl Index : cmp::Eq { pure fn eq(other: &Index) -> bool { self.entries == (*other).entries } pure fn ne(other: &Index) -> bool { !self.eq(other) } } /** * A single entry in an index * * Fields: * * * kind - The type of thing being indexed, e.g. 'Module' * * name - The name of the thing * * brief - The brief description * * link - A format-specific string representing the link target */ type IndexEntry = { kind: ~str, name: ~str, brief: Option<~str>, link: ~str }; impl IndexEntry : cmp::Eq { pure fn eq(other: &IndexEntry) -> bool { self.kind == (*other).kind && self.name == (*other).name && self.brief == (*other).brief && self.link == (*other).link } pure fn ne(other: &IndexEntry) -> bool { !self.eq(other) } } impl Doc { fn CrateDoc() -> CrateDoc { option::get(&vec::foldl(None, self.pages, |_m, page| { match *page { doc::CratePage(doc) => Some(doc), _ => None } })) } fn cratemod() -> ModDoc { self.CrateDoc().topmod } } /// Some helper methods on ModDoc, mostly for testing impl ModDoc { fn mods() -> ~[ModDoc] { do vec::filter_map(self.items) |itemtag| { match *itemtag { ModTag(ModDoc) => Some(ModDoc), _ => None } } } fn nmods() -> ~[NmodDoc] { do vec::filter_map(self.items) |itemtag| { match *itemtag { NmodTag(nModDoc) => Some(nModDoc), _ => None } } } fn fns() -> ~[FnDoc] { do vec::filter_map(self.items) |itemtag| { match *itemtag { FnTag(FnDoc) => Some(FnDoc), _ => None } } } fn consts() -> ~[ConstDoc] { do vec::filter_map(self.items) |itemtag| { match *itemtag { ConstTag(ConstDoc) => Some(ConstDoc), _ => None } } } fn enums() -> ~[EnumDoc] { do vec::filter_map(self.items) |itemtag| { match *itemtag { EnumTag(EnumDoc) => Some(EnumDoc), _ => None } } } fn traits() -> ~[TraitDoc] { do vec::filter_map(self.items) |itemtag| { match *itemtag { TraitTag(TraitDoc) => Some(TraitDoc), _ => None } } } fn impls() -> ~[ImplDoc] { do vec::filter_map(self.items) |itemtag| { match *itemtag { ImplTag(ImplDoc) => Some(ImplDoc), _ => None } } } fn types() -> ~[TyDoc] { do vec::filter_map(self.items) |itemtag| { match *itemtag { TyTag(TyDoc) => Some(TyDoc), _ => None } } } fn structs() -> ~[StructDoc] { do vec::filter_map(self.items) |itemtag| { match *itemtag { StructTag(StructDoc) => Some(StructDoc), _ => None } } } } trait PageUtils { fn mods() -> ~[ModDoc]; fn nmods() -> ~[NmodDoc]; fn fns() -> ~[FnDoc]; fn consts() -> ~[ConstDoc]; fn enums() -> ~[EnumDoc]; fn traits() -> ~[TraitDoc]; fn impls() -> ~[ImplDoc]; fn types() -> ~[TyDoc]; } impl ~[Page]: PageUtils { fn mods() -> ~[ModDoc] { do vec::filter_map(self) |page| { match *page { ItemPage(ModTag(ModDoc)) => Some(ModDoc), _ => None } } } fn nmods() -> ~[NmodDoc] { do vec::filter_map(self) |page| { match *page { ItemPage(NmodTag(nModDoc)) => Some(nModDoc), _ => None } } } fn fns() -> ~[FnDoc] { do vec::filter_map(self) |page| { match *page { ItemPage(FnTag(FnDoc)) => Some(FnDoc), _ => None } } } fn consts() -> ~[ConstDoc] { do vec::filter_map(self) |page| { match *page { ItemPage(ConstTag(ConstDoc)) => Some(ConstDoc), _ => None } } } fn enums() -> ~[EnumDoc] { do vec::filter_map(self) |page| { match *page { ItemPage(EnumTag(EnumDoc)) => Some(EnumDoc), _ => None } } } fn traits() -> ~[TraitDoc] { do vec::filter_map(self) |page| { match *page { ItemPage(TraitTag(TraitDoc)) => Some(TraitDoc), _ => None } } } fn impls() -> ~[ImplDoc] { do vec::filter_map(self) |page| { match *page { ItemPage(ImplTag(ImplDoc)) => Some(ImplDoc), _ => None } } } fn types() -> ~[TyDoc] { do vec::filter_map(self) |page| { match *page { ItemPage(TyTag(TyDoc)) => Some(TyDoc), _ => None } } } } trait Item { pure fn item() -> ItemDoc; } impl ItemTag: Item { pure fn item() -> ItemDoc { match self { doc::ModTag(doc) => doc.item, doc::NmodTag(doc) => doc.item, doc::FnTag(doc) => doc.item, doc::ConstTag(doc) => doc.item, doc::EnumTag(doc) => doc.item, doc::TraitTag(doc) => doc.item, doc::ImplTag(doc) => doc.item, doc::TyTag(doc) => doc.item, doc::StructTag(doc) => doc.item } } } impl SimpleItemDoc: Item { pure fn item() -> ItemDoc { self.item } } impl ModDoc: Item { pure fn item() -> ItemDoc { self.item } } impl NmodDoc: Item { pure fn item() -> ItemDoc { self.item } } impl EnumDoc: Item { pure fn item() -> ItemDoc { self.item } } impl TraitDoc: Item { pure fn item() -> ItemDoc { self.item } } impl ImplDoc: Item { pure fn item() -> ItemDoc { self.item } } impl StructDoc: Item { pure fn item() -> ItemDoc { self.item } } trait ItemUtils { pure fn id() -> AstId; pure fn name() -> ~str; pure fn path() -> ~[~str]; pure fn brief() -> Option<~str>; pure fn desc() -> Option<~str>; pure fn sections() -> ~[Section]; } impl A: ItemUtils { pure fn id() -> AstId { self.item().id } pure fn name() -> ~str { self.item().name } pure fn path() -> ~[~str] { self.item().path } pure fn brief() -> Option<~str> { self.item().brief } pure fn desc() -> Option<~str> { self.item().desc } pure fn sections() -> ~[Section] { self.item().sections } }