package rustdocs

import "time"

type Crate struct {
	Name        string    `json:"name"`
	Version     string    `json:"version"`
	Description string    `json:"description"`
	Modules     []*Module `json:"modules,omitempty"`
	Structs     []*Struct `json:"structs,omitempty"`
	Enums       []*Enum   `json:"enums,omitempty"`
	Traits      []*Trait  `json:"traits,omitempty"`
	Functions   []*Func   `json:"functions,omitempty"`
	Macros      []*Macro  `json:"macros,omitempty"`
	Constants   []*Const  `json:"constants,omitempty"`
	Statics     []*Static `json:"statics,omitempty"`
	DocURL      string    `json:"doc_url"`
	Repository  string    `json:"repository,omitempty"`
	License     string    `json:"license,omitempty"`
	FetchedAt   time.Time `json:"fetched_at"`
}

type Module struct {
	Name           string `json:"name"`
	Path           string `json:"path"`
	Doc            string `json:"doc,omitempty"`
	DocURL         string `json:"doc_url"`
	Stability      string `json:"stability,omitempty"`
	IsExperimental bool   `json:"is_experimental"`
}

type Struct struct {
	Name           string    `json:"name"`
	Path           string    `json:"path"`
	Doc            string    `json:"doc,omitempty"`
	Declaration    string    `json:"declaration"`
	Fields         []*Field  `json:"fields,omitempty"`
	Methods        []*Method `json:"methods,omitempty"`
	TraitImpls     []string  `json:"trait_impls,omitempty"`
	DocURL         string    `json:"doc_url"`
	Stability      string    `json:"stability,omitempty"`
	IsExperimental bool      `json:"is_experimental"`
}

type Enum struct {
	Name           string     `json:"name"`
	Path           string     `json:"path"`
	Doc            string     `json:"doc,omitempty"`
	Declaration    string     `json:"declaration"`
	Variants       []*Variant `json:"variants,omitempty"`
	Methods        []*Method  `json:"methods,omitempty"`
	DocURL         string     `json:"doc_url"`
	Stability      string     `json:"stability,omitempty"`
	IsExperimental bool       `json:"is_experimental"`
}

type Trait struct {
	Name             string    `json:"name"`
	Path             string    `json:"path"`
	Doc              string    `json:"doc,omitempty"`
	Declaration      string    `json:"declaration"`
	Methods          []*Method `json:"methods,omitempty"`
	AssociatedTypes  []string  `json:"associated_types,omitempty"`
	AssociatedConsts []string  `json:"associated_consts,omitempty"`
	DocURL           string    `json:"doc_url"`
	Stability        string    `json:"stability,omitempty"`
	IsExperimental   bool      `json:"is_experimental"`
}

type Func struct {
	Name           string `json:"name"`
	Path           string `json:"path"`
	Doc            string `json:"doc,omitempty"`
	Signature      string `json:"signature"`
	DocURL         string `json:"doc_url"`
	Stability      string `json:"stability,omitempty"`
	IsExperimental bool   `json:"is_experimental"`
	IsUnsafe       bool   `json:"is_unsafe"`
	IsConst        bool   `json:"is_const"`
	IsAsync        bool   `json:"is_async"`
}

type Macro struct {
	Name           string   `json:"name"`
	Path           string   `json:"path"`
	Doc            string   `json:"doc,omitempty"`
	Signature      string   `json:"signature,omitempty"`
	DocURL         string   `json:"doc_url"`
	Stability      string   `json:"stability,omitempty"`
	IsExperimental bool     `json:"is_experimental"`
	Examples       []string `json:"examples,omitempty"`
}

type Const struct {
	Name           string `json:"name"`
	Path           string `json:"path"`
	Doc            string `json:"doc,omitempty"`
	Type           string `json:"type,omitempty"`
	Value          string `json:"value,omitempty"`
	DocURL         string `json:"doc_url"`
	Stability      string `json:"stability,omitempty"`
	IsExperimental bool   `json:"is_experimental"`
}

type Static struct {
	Name           string `json:"name"`
	Path           string `json:"path"`
	Doc            string `json:"doc,omitempty"`
	Type           string `json:"type,omitempty"`
	IsMutable      bool   `json:"is_mutable"`
	DocURL         string `json:"doc_url"`
	Stability      string `json:"stability,omitempty"`
	IsExperimental bool   `json:"is_experimental"`
}

type Field struct {
	Name       string `json:"name"`
	Type       string `json:"type"`
	Doc        string `json:"doc,omitempty"`
	IsPub      bool   `json:"is_pub"`
	Visibility string `json:"visibility,omitempty"`
}

type Variant struct {
	Name     string   `json:"name"`
	Doc      string   `json:"doc,omitempty"`
	Fields   []string `json:"fields,omitempty"`
	IsTuple  bool     `json:"is_tuple"`
	IsStruct bool     `json:"is_struct"`
	IsUnit   bool     `json:"is_unit"`
}

type Method struct {
	Name           string   `json:"name"`
	Doc            string   `json:"doc,omitempty"`
	Signature      string   `json:"signature"`
	Receiver       string   `json:"receiver,omitempty"`
	IsUnsafe       bool     `json:"is_unsafe"`
	IsConst        bool     `json:"is_const"`
	IsAsync        bool     `json:"is_async"`
	IsDefault      bool     `json:"is_default"`
	Examples       []string `json:"examples,omitempty"`
	Stability      string   `json:"stability,omitempty"`
	IsExperimental bool     `json:"is_experimental"`
}

type SearchResult struct {
	Name           string `json:"name"`
	Path           string `json:"path"`
	Kind           string `json:"kind"`
	Description    string `json:"description,omitempty"`
	DocURL         string `json:"doc_url"`
	Stability      string `json:"stability,omitempty"`
	IsExperimental bool   `json:"is_experimental"`
}

type ItemKind string

const (
	ItemKindStruct    ItemKind = "struct"
	ItemKindEnum      ItemKind = "enum"
	ItemKindTrait     ItemKind = "trait"
	ItemKindFn        ItemKind = "fn"
	ItemKindMacro     ItemKind = "macro"
	ItemKindConst     ItemKind = "const"
	ItemKindStatic    ItemKind = "static"
	ItemKindMod       ItemKind = "mod"
	ItemKindType      ItemKind = "type"
	ItemKindUnion     ItemKind = "union"
	ItemKindPrimitive ItemKind = "primitive"
	ItemKindKeyword   ItemKind = "keyword"
	ItemKindAttr      ItemKind = "attr"
)

type Symbol struct {
	Name      string   `json:"name"`
	Kind      ItemKind `json:"kind"`
	Path      string   `json:"path"`
	Signature string   `json:"signature,omitempty"`
	Doc       string   `json:"doc,omitempty"`
	DocURL    string   `json:"doc_url"`
}
