1use std::fmt;
2
3use crate::{Docs, Ident, Render, RenderOpts, StandaloneFunc, TypeDef, Use};
4
5#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
8pub struct Interface {
9 pub(crate) name: Ident,
11
12 pub(crate) uses: Vec<Use>,
14
15 pub(crate) items: Vec<InterfaceItem>,
17
18 pub(crate) docs: Option<Docs>,
20}
21
22impl Interface {
23 pub fn new(name: impl Into<Ident>) -> Self {
25 Self {
26 name: name.into(),
27 uses: vec![],
28 items: vec![],
29 docs: None,
30 }
31 }
32
33 pub fn name(&self) -> &Ident {
34 &self.name
35 }
36
37 pub fn set_name(&mut self, name: impl Into<Ident>) {
38 self.name = name.into();
39 }
40
41 pub fn type_def(&mut self, type_def: TypeDef) {
43 self.items.push(InterfaceItem::TypeDef(type_def));
44 }
45
46 pub fn function(&mut self, function: StandaloneFunc) {
48 self.items.push(InterfaceItem::Function(function));
49 }
50
51 pub fn uses(&self) -> &[Use] {
52 &self.uses
53 }
54
55 pub fn uses_mut(&mut self) -> &mut [Use] {
56 &mut self.uses
57 }
58
59 pub fn use_(&mut self, use_: Use) {
61 self.uses.push(use_);
62 }
63
64 pub fn use_type(
66 &mut self,
67 target: impl Into<Ident>,
68 item: impl Into<Ident>,
69 rename: Option<Ident>,
70 ) {
71 let target = target.into();
72 let use_ = self.uses.iter_mut().find(|u| u.target() == &target);
73 match use_ {
74 Some(use_) => use_.item(item, rename),
75 None => {
76 self.use_({
77 let mut use_ = Use::new(target);
78 use_.item(item, rename);
79 use_
80 });
81 }
82 }
83 }
84
85 pub fn item(&mut self, item: impl Into<InterfaceItem>) {
86 self.items.push(item.into());
87 }
88
89 pub fn items(&self) -> &[InterfaceItem] {
90 &self.items
91 }
92
93 pub fn items_mut(&mut self) -> &mut Vec<InterfaceItem> {
94 &mut self.items
95 }
96
97 pub fn set_docs(&mut self, docs: Option<impl Into<Docs>>) {
99 self.docs = docs.map(|d| d.into());
100 }
101
102 pub fn docs(&self) -> &Option<Docs> {
103 &self.docs
104 }
105}
106
107#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
108#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
109#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
110pub enum InterfaceItem {
111 TypeDef(TypeDef),
112 Function(StandaloneFunc),
113}
114
115pub type InterfaceItems = Vec<InterfaceItem>;
116
117impl Render for InterfaceItems {
118 fn render(&self, f: &mut fmt::Formatter<'_>, opts: &RenderOpts) -> fmt::Result {
119 for item in self {
120 match item {
121 InterfaceItem::TypeDef(type_def) => {
122 type_def.render(f, opts)?;
123 }
124 InterfaceItem::Function(func) => {
125 if let Some(docs) = &func.docs {
126 docs.render(f, opts)?;
127 }
128 let opt_async = if func.async_ { "async " } else { "" };
129 write!(
130 f,
131 "{}{}: {opt_async}func({})",
132 opts.spaces(),
133 func.name,
134 func.params,
135 )?;
136 if let Some(ty) = &func.result {
137 write!(f, " -> {ty}")?;
138 }
139 write!(f, ";\n")?;
140 }
141 }
142 }
143 Ok(())
144 }
145}
146
147pub type InterfaceUses = Vec<Use>;
148
149impl Render for InterfaceUses {
150 fn render(&self, f: &mut fmt::Formatter<'_>, opts: &RenderOpts) -> fmt::Result {
151 for use_ in self {
152 use_.render(f, opts)?;
153 }
154 Ok(())
155 }
156}