1use shape_wire::metadata::{FieldInfo, TypeInfo, TypeKind};
12use std::fmt;
13use std::hash::Hash;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17pub struct TypeVarId(pub u32);
18
19#[derive(Clone, Debug, PartialEq, Eq, Hash)]
21pub enum SemanticType {
22 Number,
25 Integer,
27 Bool,
29 String,
31
32 Option(Box<SemanticType>),
37
38 Result {
41 ok_type: Box<SemanticType>,
42 err_type: Option<Box<SemanticType>>,
43 },
44
45 Array(Box<SemanticType>),
47
48 Struct {
51 name: String,
52 fields: Vec<(String, SemanticType)>,
53 },
54
55 Enum {
57 name: String,
58 variants: Vec<EnumVariant>,
59 type_params: Vec<String>,
60 },
61
62 TypeVar(TypeVarId),
65
66 Named(String),
68
69 Generic {
71 name: String,
72 args: Vec<SemanticType>,
73 },
74
75 Ref(Box<SemanticType>),
78 RefMut(Box<SemanticType>),
80
81 Never,
84
85 Void,
87
88 Function(Box<FunctionSignature>),
90}
91
92#[derive(Clone, Debug, PartialEq, Eq, Hash)]
94pub struct FunctionSignature {
95 pub params: Vec<FunctionParam>,
96 pub return_type: SemanticType,
97 pub is_fallible: bool, }
99
100#[derive(Clone, Debug, PartialEq, Eq, Hash)]
102pub struct FunctionParam {
103 pub name: Option<String>,
104 pub param_type: SemanticType,
105 pub optional: bool,
106}
107
108#[derive(Clone, Debug, PartialEq, Eq, Hash)]
110pub struct EnumVariant {
111 pub name: String,
112 pub payload: Option<SemanticType>,
113}
114
115impl SemanticType {
116 pub fn option(inner: SemanticType) -> Self {
120 SemanticType::Option(Box::new(inner))
121 }
122
123 pub fn result(ok_type: SemanticType) -> Self {
125 SemanticType::Result {
126 ok_type: Box::new(ok_type),
127 err_type: None,
128 }
129 }
130
131 pub fn result_with_error(ok_type: SemanticType, err_type: SemanticType) -> Self {
133 SemanticType::Result {
134 ok_type: Box::new(ok_type),
135 err_type: Some(Box::new(err_type)),
136 }
137 }
138
139 pub fn array(element: SemanticType) -> Self {
141 SemanticType::Array(Box::new(element))
142 }
143
144 pub fn shared_ref(inner: SemanticType) -> Self {
146 SemanticType::Ref(Box::new(inner))
147 }
148
149 pub fn exclusive_ref(inner: SemanticType) -> Self {
151 SemanticType::RefMut(Box::new(inner))
152 }
153
154 pub fn function(params: Vec<SemanticType>, return_type: SemanticType) -> Self {
156 SemanticType::Function(Box::new(FunctionSignature {
157 params: params
158 .into_iter()
159 .map(|t| FunctionParam {
160 name: None,
161 param_type: t,
162 optional: false,
163 })
164 .collect(),
165 return_type,
166 is_fallible: false,
167 }))
168 }
169
170 pub fn is_numeric(&self) -> bool {
174 self.is_number_family() || self.is_integer_family()
175 }
176
177 pub fn is_integer_family(&self) -> bool {
179 match self {
180 SemanticType::Integer => true,
181 SemanticType::Named(name) => matches!(
182 name.as_str(),
183 "i8" | "u8" | "i16" | "u16" | "i32" | "i64" | "u32" | "u64" | "isize" | "usize"
184 ),
185 _ => false,
186 }
187 }
188
189 pub fn is_number_family(&self) -> bool {
191 match self {
192 SemanticType::Number => true,
193 SemanticType::Named(name) => matches!(name.as_str(), "f32" | "f64"),
194 _ => false,
195 }
196 }
197
198 pub fn is_reference(&self) -> bool {
200 matches!(self, SemanticType::Ref(_) | SemanticType::RefMut(_))
201 }
202
203 pub fn is_exclusive_ref(&self) -> bool {
205 matches!(self, SemanticType::RefMut(_))
206 }
207
208 pub fn deref_type(&self) -> Option<&SemanticType> {
210 match self {
211 SemanticType::Ref(inner) | SemanticType::RefMut(inner) => Some(inner),
212 _ => None,
213 }
214 }
215
216 pub fn auto_deref(&self) -> &SemanticType {
219 match self {
220 SemanticType::Ref(inner) | SemanticType::RefMut(inner) => inner.auto_deref(),
221 other => other,
222 }
223 }
224
225 pub fn is_option(&self) -> bool {
227 matches!(self, SemanticType::Option(_))
228 }
229
230 pub fn is_result(&self) -> bool {
232 matches!(self, SemanticType::Result { .. })
233 }
234
235 pub fn option_inner(&self) -> Option<&SemanticType> {
237 match self {
238 SemanticType::Option(inner) => Some(inner),
239 _ => None,
240 }
241 }
242
243 pub fn result_ok_type(&self) -> Option<&SemanticType> {
245 match self {
246 SemanticType::Result { ok_type, .. } => Some(ok_type),
247 _ => None,
248 }
249 }
250
251 pub fn has_type_vars(&self) -> bool {
253 match self {
254 SemanticType::TypeVar(_) => true,
255 SemanticType::Option(inner) => inner.has_type_vars(),
256 SemanticType::Result { ok_type, err_type } => {
257 ok_type.has_type_vars() || err_type.as_ref().is_some_and(|e| e.has_type_vars())
258 }
259 SemanticType::Array(elem) => elem.has_type_vars(),
260 SemanticType::Struct { fields, .. } => fields.iter().any(|(_, t)| t.has_type_vars()),
261 SemanticType::Enum { variants, .. } => variants
262 .iter()
263 .any(|v| v.payload.as_ref().is_some_and(|t| t.has_type_vars())),
264 SemanticType::Function(sig) => {
265 sig.params.iter().any(|p| p.param_type.has_type_vars())
266 || sig.return_type.has_type_vars()
267 }
268 SemanticType::Generic { args, .. } => args.iter().any(|a| a.has_type_vars()),
269 _ => false,
270 }
271 }
272
273 pub fn to_type_info(&self) -> TypeInfo {
280 match self {
281 SemanticType::Number => TypeInfo::number(),
282 SemanticType::Integer => TypeInfo::integer(),
283 SemanticType::Bool => TypeInfo::bool(),
284 SemanticType::String => TypeInfo::string(),
285
286 SemanticType::Option(inner) => {
287 let inner_info = inner.to_type_info();
288 TypeInfo {
289 name: format!("Option<{}>", inner_info.name),
290 kind: TypeKind::Optional,
291 fields: None,
292 generic_params: Some(vec![inner_info]),
293 variants: None,
294 description: None,
295 metadata: None,
296 }
297 }
298
299 SemanticType::Result { ok_type, err_type } => {
300 let ok_info = ok_type.to_type_info();
301 let name = match err_type {
302 Some(e) => format!("Result<{}, {}>", ok_info.name, e.to_type_info().name),
303 None => format!("Result<{}>", ok_info.name),
304 };
305 let mut params = vec![ok_info];
306 if let Some(e) = err_type {
307 params.push(e.to_type_info());
308 }
309 TypeInfo {
310 name,
311 kind: TypeKind::Result,
312 fields: None,
313 generic_params: Some(params),
314 variants: None,
315 description: None,
316 metadata: None,
317 }
318 }
319
320 SemanticType::Array(elem) => TypeInfo::array(elem.to_type_info()),
321
322 SemanticType::Struct { name, fields } => {
323 let field_infos: Vec<FieldInfo> = fields
324 .iter()
325 .map(|(fname, ftype)| FieldInfo::required(fname, ftype.to_type_info()))
326 .collect();
327 TypeInfo::object(name, field_infos)
328 }
329
330 SemanticType::Enum { name, variants, .. } => {
331 let variant_names: Vec<String> = variants.iter().map(|v| v.name.clone()).collect();
332 TypeInfo {
333 name: name.clone(),
334 kind: TypeKind::Enum,
335 fields: None,
336 generic_params: None,
337 variants: Some(variant_names),
338 description: None,
339 metadata: None,
340 }
341 }
342
343 SemanticType::TypeVar(id) => TypeInfo::primitive(format!("T{}", id.0)),
344
345 SemanticType::Named(name) => TypeInfo::primitive(name),
346
347 SemanticType::Generic { name, args } => {
348 let arg_infos: Vec<TypeInfo> = args.iter().map(|a| a.to_type_info()).collect();
349 let arg_names: Vec<String> = arg_infos.iter().map(|a| a.name.clone()).collect();
350 TypeInfo {
351 name: format!("{}<{}>", name, arg_names.join(", ")),
352 kind: TypeKind::Object, fields: None,
354 generic_params: Some(arg_infos),
355 variants: None,
356 description: None,
357 metadata: None,
358 }
359 }
360
361 SemanticType::Ref(inner) => {
362 let inner_info = inner.to_type_info();
363 TypeInfo::primitive(format!("&{}", inner_info.name))
364 }
365 SemanticType::RefMut(inner) => {
366 let inner_info = inner.to_type_info();
367 TypeInfo::primitive(format!("&mut {}", inner_info.name))
368 }
369 SemanticType::Never => TypeInfo::primitive("Never"),
370 SemanticType::Void => TypeInfo::null(),
371
372 SemanticType::Function(sig) => {
373 let param_types: Vec<String> = sig
374 .params
375 .iter()
376 .map(|p| p.param_type.to_type_info().name)
377 .collect();
378 let ret_type = sig.return_type.to_type_info().name;
379 TypeInfo {
380 name: format!("({}) -> {}", param_types.join(", "), ret_type),
381 kind: TypeKind::Function,
382 fields: None,
383 generic_params: None,
384 variants: None,
385 description: None,
386 metadata: None,
387 }
388 }
389 }
390 }
391}
392
393impl fmt::Display for SemanticType {
394 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395 match self {
396 SemanticType::Number => write!(f, "Number"),
397 SemanticType::Integer => write!(f, "Integer"),
398 SemanticType::Bool => write!(f, "Bool"),
399 SemanticType::String => write!(f, "String"),
400 SemanticType::Option(inner) => write!(f, "Option<{}>", inner),
401 SemanticType::Result { ok_type, err_type } => match err_type {
402 Some(e) => write!(f, "Result<{}, {}>", ok_type, e),
403 None => write!(f, "Result<{}>", ok_type),
404 },
405 SemanticType::Array(elem) => write!(f, "Vec<{}>", elem),
406 SemanticType::Struct { name, .. } => write!(f, "{}", name),
407 SemanticType::Enum { name, .. } => write!(f, "{}", name),
408 SemanticType::TypeVar(id) => write!(f, "T{}", id.0),
409 SemanticType::Named(name) => write!(f, "{}", name),
410 SemanticType::Generic { name, args } => {
411 write!(f, "{}<", name)?;
412 for (i, arg) in args.iter().enumerate() {
413 if i > 0 {
414 write!(f, ", ")?;
415 }
416 write!(f, "{}", arg)?;
417 }
418 write!(f, ">")
419 }
420 SemanticType::Ref(inner) => write!(f, "&{}", inner),
421 SemanticType::RefMut(inner) => write!(f, "&mut {}", inner),
422 SemanticType::Never => write!(f, "Never"),
423 SemanticType::Void => write!(f, "Void"),
424 SemanticType::Function(sig) => {
425 write!(f, "(")?;
426 for (i, param) in sig.params.iter().enumerate() {
427 if i > 0 {
428 write!(f, ", ")?;
429 }
430 write!(f, "{}", param.param_type)?;
431 }
432 write!(f, ") -> {}", sig.return_type)
433 }
434 }
435 }
436}
437
438#[cfg(test)]
439mod tests {
440 use super::*;
441
442 #[test]
443 fn test_option_creation() {
444 let opt = SemanticType::option(SemanticType::Number);
445 assert!(opt.is_option());
446 assert_eq!(opt.option_inner(), Some(&SemanticType::Number));
447 }
448
449 #[test]
450 fn test_result_creation() {
451 let res = SemanticType::result(SemanticType::Number);
452 assert!(res.is_result());
453 match &res {
454 SemanticType::Result { ok_type, err_type } => {
455 assert_eq!(**ok_type, SemanticType::Number);
456 assert!(err_type.is_none());
457 }
458 _ => panic!("Expected Result"),
459 }
460 }
461
462 #[test]
463 fn test_display() {
464 assert_eq!(format!("{}", SemanticType::Number), "Number");
465 assert_eq!(
466 format!("{}", SemanticType::option(SemanticType::Number)),
467 "Option<Number>"
468 );
469 assert_eq!(
470 format!("{}", SemanticType::result(SemanticType::String)),
471 "Result<String>"
472 );
473 }
474
475 #[test]
476 fn test_to_type_info_primitives() {
477 let num = SemanticType::Number.to_type_info();
478 assert_eq!(num.name, "Number");
479 assert_eq!(num.kind, TypeKind::Primitive);
480
481 let int = SemanticType::Integer.to_type_info();
482 assert_eq!(int.name, "Integer");
483
484 let bool_t = SemanticType::Bool.to_type_info();
485 assert_eq!(bool_t.name, "Bool");
486
487 let string_t = SemanticType::String.to_type_info();
488 assert_eq!(string_t.name, "String");
489 }
490
491 #[test]
492 fn test_to_type_info_option() {
493 let opt = SemanticType::option(SemanticType::Number).to_type_info();
494 assert_eq!(opt.name, "Option<Number>");
495 assert_eq!(opt.kind, TypeKind::Optional);
496 assert!(opt.generic_params.is_some());
497 assert_eq!(opt.generic_params.as_ref().unwrap().len(), 1);
498 }
499
500 #[test]
501 fn test_to_type_info_result() {
502 let res = SemanticType::result(SemanticType::String).to_type_info();
503 assert_eq!(res.name, "Result<String>");
504 assert_eq!(res.kind, TypeKind::Result);
505
506 let res_with_err =
507 SemanticType::result_with_error(SemanticType::Number, SemanticType::String)
508 .to_type_info();
509 assert_eq!(res_with_err.name, "Result<Number, String>");
510 }
511
512 #[test]
513 fn test_to_type_info_array() {
514 let arr = SemanticType::array(SemanticType::Bool).to_type_info();
515 assert_eq!(arr.name, "Array<Bool>");
516 assert_eq!(arr.kind, TypeKind::Array);
517 }
518
519 #[test]
520 fn test_named_width_numeric_families() {
521 assert!(SemanticType::Named("i16".to_string()).is_numeric());
522 assert!(SemanticType::Named("u64".to_string()).is_integer_family());
523 assert!(SemanticType::Named("f32".to_string()).is_number_family());
524 assert!(SemanticType::Named("f64".to_string()).is_numeric());
525 assert!(!SemanticType::Named("Candle".to_string()).is_numeric());
526 }
527
528 #[test]
531 fn test_shared_ref_creation() {
532 let r = SemanticType::shared_ref(SemanticType::Integer);
533 assert!(r.is_reference());
534 assert!(!r.is_exclusive_ref());
535 assert_eq!(r.deref_type(), Some(&SemanticType::Integer));
536 }
537
538 #[test]
539 fn test_exclusive_ref_creation() {
540 let r = SemanticType::exclusive_ref(SemanticType::Integer);
541 assert!(r.is_reference());
542 assert!(r.is_exclusive_ref());
543 assert_eq!(r.deref_type(), Some(&SemanticType::Integer));
544 }
545
546 #[test]
547 fn test_auto_deref() {
548 let r = SemanticType::shared_ref(SemanticType::Integer);
549 assert_eq!(r.auto_deref(), &SemanticType::Integer);
550
551 assert_eq!(SemanticType::Integer.auto_deref(), &SemanticType::Integer);
553
554 let nested = SemanticType::shared_ref(SemanticType::shared_ref(SemanticType::Bool));
556 assert_eq!(nested.auto_deref(), &SemanticType::Bool);
557 }
558
559 #[test]
560 fn test_ref_display() {
561 let shared = SemanticType::shared_ref(SemanticType::Integer);
562 assert_eq!(format!("{}", shared), "&Integer");
563
564 let exclusive = SemanticType::exclusive_ref(SemanticType::Integer);
565 assert_eq!(format!("{}", exclusive), "&mut Integer");
566 }
567
568 #[test]
569 fn test_ref_to_type_info() {
570 let r = SemanticType::shared_ref(SemanticType::Number);
571 let info = r.to_type_info();
572 assert_eq!(info.name, "&Number");
573 }
574
575 #[test]
576 fn test_ref_is_not_numeric() {
577 let r = SemanticType::shared_ref(SemanticType::Integer);
578 assert!(!r.is_numeric());
579 }
580
581 #[test]
582 fn test_non_ref_deref_type_is_none() {
583 assert!(SemanticType::Integer.deref_type().is_none());
584 assert!(SemanticType::String.deref_type().is_none());
585 }
586}