openapi_nexus_go/ast/
go_expression.rs1use pretty::RcDoc;
4use serde::{Deserialize, Serialize};
5
6use crate::ast::ty::GoPrimitive;
7use openapi_nexus_core::traits::ToRcDoc;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
11pub enum GoExpression {
12 Primitive(GoPrimitive),
14 Pointer(Box<GoExpression>),
16 Slice(Box<GoExpression>),
18 Map {
20 key: Box<GoExpression>,
21 value: Box<GoExpression>,
22 },
23 Reference(String),
25 Interface(String),
27 Function {
29 params: Vec<GoExpression>,
30 returns: Vec<GoExpression>,
31 },
32 Any,
34 OptionalNullable(Box<GoExpression>),
36}
37
38impl ToRcDoc for GoExpression {
39 fn to_rcdoc(&self) -> RcDoc<'static, ()> {
40 match self {
41 GoExpression::Primitive(p) => p.to_rcdoc(),
42 GoExpression::Pointer(inner) => RcDoc::text("*").append(inner.to_rcdoc()),
43 GoExpression::Slice(inner) => RcDoc::text("[]").append(inner.to_rcdoc()),
44 GoExpression::Map { key, value } => RcDoc::text("map[")
45 .append(key.to_rcdoc())
46 .append(RcDoc::text("]"))
47 .append(value.to_rcdoc()),
48 GoExpression::Reference(name) => RcDoc::text(name.clone()),
49 GoExpression::Interface(name) => RcDoc::text(name.clone()),
50 GoExpression::Function { params, returns } => {
51 let param_docs: Vec<_> = params.iter().map(|p| p.to_rcdoc()).collect();
52 let params_doc = if param_docs.is_empty() {
53 RcDoc::text("()")
54 } else {
55 RcDoc::text("(")
56 .append(RcDoc::intersperse(param_docs, RcDoc::text(", ")))
57 .append(RcDoc::text(")"))
58 };
59
60 let returns_doc = if returns.is_empty() {
61 RcDoc::nil()
62 } else if returns.len() == 1 {
63 RcDoc::space()
64 .append(RcDoc::text("("))
65 .append(returns[0].to_rcdoc())
66 .append(RcDoc::text(")"))
67 } else {
68 let return_docs: Vec<_> = returns.iter().map(|r| r.to_rcdoc()).collect();
69 RcDoc::space()
70 .append(RcDoc::text("("))
71 .append(RcDoc::intersperse(return_docs, RcDoc::text(", ")))
72 .append(RcDoc::text(")"))
73 };
74
75 RcDoc::text("func")
76 .append(RcDoc::space())
77 .append(params_doc)
78 .append(returns_doc)
79 }
80 GoExpression::Any => RcDoc::text("interface{}"),
81 GoExpression::OptionalNullable(inner) => {
82 RcDoc::text("optionalnullable.OptionalNullable[")
83 .append(inner.to_rcdoc())
84 .append(RcDoc::text("]"))
85 }
86 }
87 }
88}
89
90impl GoExpression {
91 pub fn reference(name: String) -> Self {
93 GoExpression::Reference(name)
94 }
95
96 pub fn pointer(inner: GoExpression) -> Self {
98 GoExpression::Pointer(Box::new(inner))
99 }
100
101 pub fn slice(inner: GoExpression) -> Self {
103 GoExpression::Slice(Box::new(inner))
104 }
105
106 pub fn map(key: GoExpression, value: GoExpression) -> Self {
108 GoExpression::Map {
109 key: Box::new(key),
110 value: Box::new(value),
111 }
112 }
113
114 pub fn optional_nullable(inner: GoExpression) -> Self {
116 GoExpression::OptionalNullable(Box::new(inner))
117 }
118}