1use std::{
2 collections::HashSet,
3 fmt::{self, Display},
4};
5
6use serde::{Deserialize, Serialize};
7
8pub mod parse;
9
10#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
11pub struct HitItem {
12 pub path: Vec<String>,
13 pub link: Vec<String>,
14 pub docs: Option<String>,
15}
16
17#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
18pub struct Query {
19 pub name: Option<Symbol>,
20 pub kind: Option<QueryKind>,
21}
22
23impl Query {
24 pub fn args(&self) -> Option<Vec<Argument>> {
25 self.kind
26 .as_ref()
27 .map(|kind| {
28 let QueryKind::FunctionQuery(f) = kind;
29 &f.decl
30 })
31 .and_then(|decl| decl.inputs.clone())
32 }
33}
34
35impl Display for Query {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 write!(f, "fn")?;
38 if let Some(name) = &self.name {
39 write!(f, " {}", name)?;
40 }
41 if let Some(kind) = &self.kind {
42 match kind {
43 QueryKind::FunctionQuery(func) => {
44 write!(f, "{}", func.decl)?;
45 }
46 }
47 }
48 Ok(())
49 }
50}
51
52#[non_exhaustive]
53#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
54pub enum QueryKind {
55 FunctionQuery(Function),
56}
57
58#[non_exhaustive]
59#[derive(Clone, Debug, Eq, Hash, Serialize, Deserialize, PartialEq)]
60pub enum Qualifier {
61 Async,
62 Unsafe,
63 Const,
64}
65
66#[non_exhaustive]
67#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
68pub struct Function {
69 pub decl: FnDecl,
70 pub qualifiers: HashSet<Qualifier>,
71}
72
73impl Display for FnDecl {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 write!(f, "(")?;
76 if let Some(inputs) = &self.inputs {
77 let input_strs: Vec<String> = inputs
78 .iter()
79 .map(|arg| match (&arg.name, &arg.ty) {
80 (Some(name), Some(ty)) => format!("{}: {}", name, ty),
81 (Some(name), None) => format!("{}: _", name),
82 (None, Some(ty)) => format!("{}", ty),
83 (None, None) => "_".to_string(),
84 })
85 .collect();
86 write!(f, "{}", input_strs.join(", "))?;
87 } else {
88 write!(f, "..")?;
89 }
90 write!(f, ")")?;
91 if let Some(output) = &self.output {
92 match output {
93 FnRetTy::Return(ty) => write!(f, " -> {}", ty)?,
94 FnRetTy::DefaultReturn => {}
95 }
96 }
97 Ok(())
98 }
99}
100
101#[non_exhaustive]
102#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
103pub enum GenericArgs {
104 AngleBracketed {
105 args: Vec<Option<GenericArg>>, },
107 }
109
110#[non_exhaustive]
111#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
112pub enum GenericArg {
113 Type(Type),
115 }
117#[non_exhaustive]
118#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
119pub struct FnDecl {
120 pub inputs: Option<Vec<Argument>>,
121 pub output: Option<FnRetTy>,
122 }
124
125#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
126pub struct Argument {
127 pub ty: Option<Type>,
128 pub name: Option<Symbol>,
129}
130
131#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
132pub enum FnRetTy {
133 Return(Type),
134 DefaultReturn,
135}
136
137pub type Symbol = String;
138
139#[non_exhaustive]
140#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
141pub enum Type {
142 UnresolvedPath {
144 name: Symbol,
145 args: Option<Box<GenericArgs>>,
146 },
147 Generic(String),
148 Primitive(PrimitiveType),
149 Tuple(Vec<Option<Type>>),
150 Slice(Option<Box<Type>>),
151 Never,
152 RawPointer {
153 mutable: bool,
154 type_: Box<Type>,
155 },
156 BorrowedRef {
157 mutable: bool,
158 type_: Box<Type>,
159 },
160}
161
162impl Display for Type {
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 use Type::*;
165 match self {
166 UnresolvedPath { name, args } => {
167 if let Some(args) = args {
168 write!(f, "{}<{:?}>", name, args)
169 } else {
170 write!(f, "{}", name)
171 }
172 }
173 Generic(name) => write!(f, "{}", name),
174 Primitive(prim) => write!(f, "{}", prim.as_str()),
175 Tuple(types) => {
176 let types: Vec<String> = types
177 .iter()
178 .map(|ty| match ty {
179 Some(ty) => format!("{}", ty),
180 None => "_".to_string(),
181 })
182 .collect();
183 write!(f, "({})", types.join(", "))
184 }
185 Slice(ty) => match ty {
186 Some(ty) => write!(f, "[{}]", ty),
187 None => write!(f, "[_]",),
188 },
189 Never => write!(f, "!"),
190 RawPointer { mutable, type_ } => {
191 if *mutable {
192 write!(f, "*mut {}", type_)
193 } else {
194 write!(f, "*const {}", type_)
195 }
196 }
197 BorrowedRef { mutable, type_ } => {
198 if *mutable {
199 write!(f, "&mut {}", type_)
200 } else {
201 write!(f, "&{}", type_)
202 }
203 }
204 }
205 }
206}
207
208impl Type {
209 pub fn inner_type(&self) -> &Self {
210 match self {
211 Type::RawPointer { type_, .. } => type_.inner_type(),
212 Type::BorrowedRef { type_, .. } => type_.inner_type(),
213 _ => self,
214 }
215 }
216}
217
218#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
221pub enum PrimitiveType {
222 Isize,
223 I8,
224 I16,
225 I32,
226 I64,
227 I128,
228 Usize,
229 U8,
230 U16,
231 U32,
232 U64,
233 U128,
234 F32,
235 F64,
236 Char,
237 Bool,
238 Str,
239 Unit,
240 Never,
241}
242
243impl PrimitiveType {
244 pub fn as_str(&self) -> &str {
245 use PrimitiveType::*;
246 match self {
247 Isize => "isize",
248 I8 => "i8",
249 I16 => "i16",
250 I32 => "i32",
251 I64 => "i64",
252 I128 => "i128",
253 Usize => "usize",
254 U8 => "u8",
255 U16 => "u16",
256 U32 => "u32",
257 U64 => "u64",
258 U128 => "u128",
259 F32 => "f32",
260 F64 => "f64",
261 Char => "char",
262 Bool => "bool",
263 Str => "str",
264 Unit => "unit",
265 Never => "never",
266 }
267 }
268}