blob: 0764d9e2432687cb7cd3d5de53d905d961d4fce6 [file] [log] [blame]
//! 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<Index>
};
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<Index>
};
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:Item> 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
}
}