Skip to content

Commit b43b25f

Browse files
doepnernstano45
andauthored
changed parsing to use a simplified operation model so we can access types on each message separately (#44)
* changed parsing to use a simplified operation model so we can access types on each message separately * fix fmt --------- Co-authored-by: Stanislav Kosorin <stanislav.kosorin@cresta.ai>
1 parent 8ed6c9a commit b43b25f

13 files changed

Lines changed: 189 additions & 188 deletions

File tree

example/specs/basic.yaml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,24 @@ channels:
2222
operationId: userSignedUp
2323
summary: send welcome email to user
2424
message:
25-
payload:
26-
type: string
25+
payload:
26+
type: object
27+
properties:
28+
username:
29+
type: string
30+
password:
31+
type: string
32+
age:
33+
type: number
2734
user/buy:
2835
subscribe:
29-
operationId: userBought
3036
summary: User bought something
3137
message:
3238
payload:
33-
type: string
39+
type: object
40+
properties:
41+
item_id:
42+
type: string
43+
amount:
44+
type: number
3445

src/asyncapi_model/api.rs

Lines changed: 7 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use indexmap::IndexMap;
22
use serde::{Deserialize, Serialize};
33

4-
use super::{
5-
Channel, Components, ExternalDocumentation, Info, Operation, Payload, ReferenceOr, Schema,
6-
Server, Tag,
7-
};
4+
use crate::template_model::{simplify_operation, SimplifiedOperation};
5+
6+
use super::{Channel, Components, ExternalDocumentation, Info, ReferenceOr, Server, Tag};
87

98
/// This is the root document object for the API specification.
109
/// It combines resource listing and API declaration together into one document.
@@ -170,62 +169,26 @@ pub struct AsyncAPI {
170169
pub extensions: IndexMap<String, serde_json::Value>,
171170
}
172171
impl AsyncAPI {
173-
pub fn get_all_channels_operations(&self) -> Vec<(&String, &Operation)> {
174-
self.channels
175-
.iter()
176-
.flat_map(|(channel_name, channel)| {
177-
vec![
178-
channel
179-
.publish
180-
.as_ref()
181-
.map(|operation| (channel_name, operation)),
182-
channel
183-
.subscribe
184-
.as_ref()
185-
.map(|operation| (channel_name, operation)),
186-
]
187-
})
188-
.flatten()
189-
.collect()
190-
}
191-
pub fn get_subscribe_channels_operations(&self) -> Vec<(&String, &Operation)> {
172+
pub fn get_subscribe_channels_operations(&self) -> Vec<(&String, SimplifiedOperation)> {
192173
self.channels
193174
.iter()
194175
.filter_map(|(channel_name, channel)| {
195176
channel
196177
.subscribe
197178
.as_ref()
198-
.map(|operation| (channel_name, operation))
179+
.map(|operation| (channel_name, simplify_operation(operation, channel_name)))
199180
})
200181
.collect()
201182
}
202-
pub fn get_publish_channels_operations(&self) -> Vec<(&String, &Operation)> {
183+
pub fn get_publish_channels_operations(&self) -> Vec<(&String, SimplifiedOperation)> {
203184
self.channels
204185
.iter()
205186
.filter_map(|(channel_name, channel)| {
206187
channel
207188
.publish
208189
.as_ref()
209-
.map(|operation| (channel_name, operation))
190+
.map(|operation| (channel_name, simplify_operation(operation, channel_name)))
210191
})
211192
.collect()
212193
}
213-
pub fn get_components(&self) -> Option<&Components> {
214-
self.components.as_ref()
215-
}
216-
pub fn get_schema_from_reference(&self, message_name: &str) -> &Schema {
217-
self.get_components()
218-
.and_then(|components| {
219-
let message_or_ref = components.messages.get(message_name).unwrap();
220-
let payload = match message_or_ref {
221-
ReferenceOr::Item(message) => message.payload.as_ref().unwrap(),
222-
ReferenceOr::Reference { .. } => return None, // or handle the reference case
223-
};
224-
Some(match payload {
225-
Payload::Schema(schema) => schema,
226-
Payload::Any(_) => return None,
227-
})
228-
})
229-
.unwrap()
230-
}
231194
}

src/main.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ fn main() {
4848
&async_config,
4949
&output_path.join("Readme.md"),
5050
);
51+
println!("file generation finished, adding dependencies...");
52+
5153
// make output a compilable project
5254
cargo_init_project(output_path);
5355
cargo_fmt(&output_path.join("src/main.rs"));
@@ -56,8 +58,5 @@ fn main() {
5658
cargo_add(output_path, "futures", None);
5759
cargo_add(output_path, "serde", None);
5860
println!("generating docs...");
59-
println!(
60-
"this may take a while, you can already use the generated project in the output directory"
61-
);
6261
cargo_generate_rustdoc(output_path);
6362
}

src/parser/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
mod common;
2+
mod parse_template_context;
23
mod preprocessor;
3-
mod pubsub;
44
mod schema_parser;
55
mod validator;
6-
pub use common::parse_spec_to_model;
7-
pub use pubsub::spec_to_pubsub_template_type;
6+
pub use common::{parse_spec_to_model, validate_identifier_string};
7+
pub use parse_template_context::spec_to_pubsub_template_type;
8+
pub use schema_parser::schema_parser_mapper;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use crate::{
2+
asyncapi_model::{AsyncAPI, ReferenceOr},
3+
template_model::TemplateContext,
4+
};
5+
use std::io;
6+
7+
pub fn spec_to_pubsub_template_type<'a>(
8+
spec: &'a AsyncAPI,
9+
) -> Result<TemplateContext<'a>, io::Error> {
10+
let item = spec.servers.first().unwrap().1;
11+
let server = match item {
12+
ReferenceOr::Item(it) => it,
13+
ReferenceOr::Reference { reference: _ } => None.unwrap(),
14+
};
15+
16+
let publish_channels = spec.get_publish_channels_operations();
17+
let subscribe_channels = spec.get_subscribe_channels_operations();
18+
19+
let pubsub_template: TemplateContext<'a> = TemplateContext {
20+
server,
21+
subscribe_channels,
22+
publish_channels,
23+
title: &spec.info.title,
24+
description: &spec.info.description,
25+
};
26+
Ok(pubsub_template)
27+
}

src/parser/preprocessor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::parser::common::validate_identifier_string;
22
use serde_json::json;
3-
use std::collections::HashSet;
3+
use std::{collections::HashSet, panic};
44

55
pub fn resolve_json_path(json: serde_json::Value, path: &str) -> serde_json::Value {
66
let parts = path.split('/').collect::<Vec<&str>>();

src/parser/pubsub.rs

Lines changed: 0 additions & 115 deletions
This file was deleted.

src/parser/schema_parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ fn object_schema_to_string(
3636
property_name: &str,
3737
all_structs: &mut HashMap<String, String>,
3838
) -> Result<String, SchemaParserError> {
39-
let before_string = format!(
39+
let before_string: String = format!(
4040
"#[derive(Clone, Debug, Deserialize, Serialize)]\npub struct {} {{\n",
4141
validate_identifier_string(property_name)
4242
);

src/template_model/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
1-
mod pubsub_template;
2-
pub use pubsub_template::PubsubTemplate;
1+
mod simplified_operation;
2+
mod template_context;
3+
pub use simplified_operation::{
4+
simplify_message, simplify_operation, simplify_schema, SimplifiedMessage, SimplifiedOperation,
5+
SimplifiedSchema,
6+
};
7+
pub use template_context::TemplateContext;

0 commit comments

Comments
 (0)