1use ploidy_core::ir::{ExtendableView, PrimitiveType, PrimitiveView};
2use proc_macro2::TokenStream;
3use quote::{ToTokens, TokenStreamExt, quote};
4
5use super::config::DateTimeFormat;
6
7#[derive(Clone, Copy, Debug)]
8pub struct CodegenPrimitive<'a> {
9 ty: &'a PrimitiveView<'a>,
10}
11
12impl<'a> CodegenPrimitive<'a> {
13 pub fn new(ty: &'a PrimitiveView<'a>) -> Self {
14 Self { ty }
15 }
16}
17
18impl<'a> ToTokens for CodegenPrimitive<'a> {
19 fn to_tokens(&self, tokens: &mut TokenStream) {
20 tokens.append_all(match self.ty.ty() {
21 PrimitiveType::String => quote! { ::std::string::String },
22 PrimitiveType::I8 => quote! { i8 },
23 PrimitiveType::U8 => quote! { u8 },
24 PrimitiveType::I16 => quote! { i16 },
25 PrimitiveType::U16 => quote! { u16 },
26 PrimitiveType::I32 => quote! { i32 },
27 PrimitiveType::U32 => quote! { u32 },
28 PrimitiveType::I64 => quote! { i64 },
29 PrimitiveType::U64 => quote! { u64 },
30 PrimitiveType::F32 => quote! { f32 },
31 PrimitiveType::F64 => quote! { f64 },
32 PrimitiveType::Bool => quote! { bool },
33 PrimitiveType::DateTime => {
34 let format = self
35 .ty
36 .extensions()
37 .get::<DateTimeFormat>()
38 .as_deref()
39 .copied()
40 .unwrap_or_default();
41 match format {
42 DateTimeFormat::Rfc3339 => {
43 quote! { ::ploidy_util::chrono::DateTime<::ploidy_util::chrono::Utc> }
44 }
45 DateTimeFormat::UnixSeconds => {
46 quote! { ::ploidy_util::date_time::UnixSeconds }
47 }
48 DateTimeFormat::UnixMilliseconds => {
49 quote! { ::ploidy_util::date_time::UnixMilliseconds }
50 }
51 DateTimeFormat::UnixMicroseconds => {
52 quote! { ::ploidy_util::date_time::UnixMicroseconds }
53 }
54 DateTimeFormat::UnixNanoseconds => {
55 quote! { ::ploidy_util::date_time::UnixNanoseconds }
56 }
57 }
58 }
59 PrimitiveType::UnixTime => quote! { ::ploidy_util::date_time::UnixSeconds },
60 PrimitiveType::Date => quote! { ::ploidy_util::chrono::NaiveDate },
61 PrimitiveType::Url => quote! { ::ploidy_util::url::Url },
62 PrimitiveType::Uuid => quote! { ::ploidy_util::uuid::Uuid },
63 PrimitiveType::Bytes => quote! { ::ploidy_util::binary::Base64 },
64 PrimitiveType::Binary => quote! { ::ploidy_util::serde_bytes::ByteBuf },
65 });
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 use itertools::Itertools;
74 use ploidy_core::{
75 arena::Arena,
76 ir::{RawGraph, Spec},
77 parse::Document,
78 };
79 use pretty_assertions::assert_eq;
80 use syn::parse_quote;
81
82 use crate::{CodegenConfig, CodegenGraph, DateTimeFormat};
83
84 #[test]
85 fn test_codegen_primitive_string() {
86 let doc = Document::from_yaml(indoc::indoc! {"
87 openapi: 3.0.0
88 info:
89 title: Test
90 version: 1.0.0
91 paths: {}
92 components:
93 schemas:
94 Test:
95 type: string
96 "})
97 .unwrap();
98 let arena = Arena::new();
99 let spec = Spec::from_doc(&arena, &doc).unwrap();
100 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
101 let primitives = graph.primitives().collect_vec();
102 let [ty] = &*primitives else {
103 panic!("expected string; got `{primitives:?}`");
104 };
105 let p = CodegenPrimitive::new(ty);
106 let actual: syn::Type = parse_quote!(#p);
107 let expected: syn::Type = parse_quote!(::std::string::String);
108 assert_eq!(actual, expected);
109 }
110
111 #[test]
112 fn test_codegen_primitive_i8() {
113 let doc = Document::from_yaml(indoc::indoc! {"
114 openapi: 3.0.0
115 info:
116 title: Test
117 version: 1.0.0
118 paths: {}
119 components:
120 schemas:
121 Test:
122 type: object
123 required: [value]
124 properties:
125 value:
126 type: integer
127 format: int8
128 "})
129 .unwrap();
130 let arena = Arena::new();
131 let spec = Spec::from_doc(&arena, &doc).unwrap();
132 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
133 let primitives = graph.primitives().collect_vec();
134 let [ty] = &*primitives else {
135 panic!("expected i8; got `{primitives:?}`");
136 };
137 let p = CodegenPrimitive::new(ty);
138 let actual: syn::Type = parse_quote!(#p);
139 let expected: syn::Type = parse_quote!(i8);
140 assert_eq!(actual, expected);
141 }
142
143 #[test]
144 fn test_codegen_primitive_u8() {
145 let doc = Document::from_yaml(indoc::indoc! {"
146 openapi: 3.0.0
147 info:
148 title: Test
149 version: 1.0.0
150 paths: {}
151 components:
152 schemas:
153 Test:
154 type: object
155 required: [value]
156 properties:
157 value:
158 type: integer
159 format: uint8
160 "})
161 .unwrap();
162 let arena = Arena::new();
163 let spec = Spec::from_doc(&arena, &doc).unwrap();
164 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
165 let primitives = graph.primitives().collect_vec();
166 let [ty] = &*primitives else {
167 panic!("expected u8; got `{primitives:?}`");
168 };
169 let p = CodegenPrimitive::new(ty);
170 let actual: syn::Type = parse_quote!(#p);
171 let expected: syn::Type = parse_quote!(u8);
172 assert_eq!(actual, expected);
173 }
174
175 #[test]
176 fn test_codegen_primitive_i16() {
177 let doc = Document::from_yaml(indoc::indoc! {"
178 openapi: 3.0.0
179 info:
180 title: Test
181 version: 1.0.0
182 paths: {}
183 components:
184 schemas:
185 Test:
186 type: object
187 required: [value]
188 properties:
189 value:
190 type: integer
191 format: int16
192 "})
193 .unwrap();
194 let arena = Arena::new();
195 let spec = Spec::from_doc(&arena, &doc).unwrap();
196 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
197 let primitives = graph.primitives().collect_vec();
198 let [ty] = &*primitives else {
199 panic!("expected i16; got `{primitives:?}`");
200 };
201 let p = CodegenPrimitive::new(ty);
202 let actual: syn::Type = parse_quote!(#p);
203 let expected: syn::Type = parse_quote!(i16);
204 assert_eq!(actual, expected);
205 }
206
207 #[test]
208 fn test_codegen_primitive_u16() {
209 let doc = Document::from_yaml(indoc::indoc! {"
210 openapi: 3.0.0
211 info:
212 title: Test
213 version: 1.0.0
214 paths: {}
215 components:
216 schemas:
217 Test:
218 type: object
219 required: [value]
220 properties:
221 value:
222 type: integer
223 format: uint16
224 "})
225 .unwrap();
226 let arena = Arena::new();
227 let spec = Spec::from_doc(&arena, &doc).unwrap();
228 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
229 let primitives = graph.primitives().collect_vec();
230 let [ty] = &*primitives else {
231 panic!("expected u16; got `{primitives:?}`");
232 };
233 let p = CodegenPrimitive::new(ty);
234 let actual: syn::Type = parse_quote!(#p);
235 let expected: syn::Type = parse_quote!(u16);
236 assert_eq!(actual, expected);
237 }
238
239 #[test]
240 fn test_codegen_primitive_i32() {
241 let doc = Document::from_yaml(indoc::indoc! {"
242 openapi: 3.0.0
243 info:
244 title: Test
245 version: 1.0.0
246 paths: {}
247 components:
248 schemas:
249 Test:
250 type: object
251 required: [value]
252 properties:
253 value:
254 type: integer
255 format: int32
256 "})
257 .unwrap();
258 let arena = Arena::new();
259 let spec = Spec::from_doc(&arena, &doc).unwrap();
260 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
261 let primitives = graph.primitives().collect_vec();
262 let [ty] = &*primitives else {
263 panic!("expected string; got `{primitives:?}`");
264 };
265 let p = CodegenPrimitive::new(ty);
266 let actual: syn::Type = parse_quote!(#p);
267 let expected: syn::Type = parse_quote!(i32);
268 assert_eq!(actual, expected);
269 }
270
271 #[test]
272 fn test_codegen_primitive_u32() {
273 let doc = Document::from_yaml(indoc::indoc! {"
274 openapi: 3.0.0
275 info:
276 title: Test
277 version: 1.0.0
278 paths: {}
279 components:
280 schemas:
281 Test:
282 type: object
283 required: [value]
284 properties:
285 value:
286 type: integer
287 format: uint32
288 "})
289 .unwrap();
290 let arena = Arena::new();
291 let spec = Spec::from_doc(&arena, &doc).unwrap();
292 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
293 let primitives = graph.primitives().collect_vec();
294 let [ty] = &*primitives else {
295 panic!("expected u32; got `{primitives:?}`");
296 };
297 let p = CodegenPrimitive::new(ty);
298 let actual: syn::Type = parse_quote!(#p);
299 let expected: syn::Type = parse_quote!(u32);
300 assert_eq!(actual, expected);
301 }
302
303 #[test]
304 fn test_codegen_primitive_i64() {
305 let doc = Document::from_yaml(indoc::indoc! {"
306 openapi: 3.0.0
307 info:
308 title: Test
309 version: 1.0.0
310 paths: {}
311 components:
312 schemas:
313 Test:
314 type: object
315 required: [value]
316 properties:
317 value:
318 type: integer
319 format: int64
320 "})
321 .unwrap();
322 let arena = Arena::new();
323 let spec = Spec::from_doc(&arena, &doc).unwrap();
324 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
325 let primitives = graph.primitives().collect_vec();
326 let [ty] = &*primitives else {
327 panic!("expected i64; got `{primitives:?}`");
328 };
329 let p = CodegenPrimitive::new(ty);
330 let actual: syn::Type = parse_quote!(#p);
331 let expected: syn::Type = parse_quote!(i64);
332 assert_eq!(actual, expected);
333 }
334
335 #[test]
336 fn test_codegen_primitive_u64() {
337 let doc = Document::from_yaml(indoc::indoc! {"
338 openapi: 3.0.0
339 info:
340 title: Test
341 version: 1.0.0
342 paths: {}
343 components:
344 schemas:
345 Test:
346 type: object
347 required: [value]
348 properties:
349 value:
350 type: integer
351 format: uint64
352 "})
353 .unwrap();
354 let arena = Arena::new();
355 let spec = Spec::from_doc(&arena, &doc).unwrap();
356 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
357 let primitives = graph.primitives().collect_vec();
358 let [ty] = &*primitives else {
359 panic!("expected u64; got `{primitives:?}`");
360 };
361 let p = CodegenPrimitive::new(ty);
362 let actual: syn::Type = parse_quote!(#p);
363 let expected: syn::Type = parse_quote!(u64);
364 assert_eq!(actual, expected);
365 }
366
367 #[test]
368 fn test_codegen_primitive_f32() {
369 let doc = Document::from_yaml(indoc::indoc! {"
370 openapi: 3.0.0
371 info:
372 title: Test
373 version: 1.0.0
374 paths: {}
375 components:
376 schemas:
377 Test:
378 type: object
379 required: [value]
380 properties:
381 value:
382 type: number
383 format: float
384 "})
385 .unwrap();
386 let arena = Arena::new();
387 let spec = Spec::from_doc(&arena, &doc).unwrap();
388 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
389 let primitives = graph.primitives().collect_vec();
390 let [ty] = &*primitives else {
391 panic!("expected f32; got `{primitives:?}`");
392 };
393 let p = CodegenPrimitive::new(ty);
394 let actual: syn::Type = parse_quote!(#p);
395 let expected: syn::Type = parse_quote!(f32);
396 assert_eq!(actual, expected);
397 }
398
399 #[test]
400 fn test_codegen_primitive_f64() {
401 let doc = Document::from_yaml(indoc::indoc! {"
402 openapi: 3.0.0
403 info:
404 title: Test
405 version: 1.0.0
406 paths: {}
407 components:
408 schemas:
409 Test:
410 type: object
411 required: [value]
412 properties:
413 value:
414 type: number
415 format: double
416 "})
417 .unwrap();
418 let arena = Arena::new();
419 let spec = Spec::from_doc(&arena, &doc).unwrap();
420 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
421 let primitives = graph.primitives().collect_vec();
422 let [ty] = &*primitives else {
423 panic!("expected f64; got `{primitives:?}`");
424 };
425 let p = CodegenPrimitive::new(ty);
426 let actual: syn::Type = parse_quote!(#p);
427 let expected: syn::Type = parse_quote!(f64);
428 assert_eq!(actual, expected);
429 }
430
431 #[test]
432 fn test_codegen_primitive_bool() {
433 let doc = Document::from_yaml(indoc::indoc! {"
434 openapi: 3.0.0
435 info:
436 title: Test
437 version: 1.0.0
438 paths: {}
439 components:
440 schemas:
441 Test:
442 type: object
443 required: [value]
444 properties:
445 value:
446 type: boolean
447 "})
448 .unwrap();
449 let arena = Arena::new();
450 let spec = Spec::from_doc(&arena, &doc).unwrap();
451 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
452 let primitives = graph.primitives().collect_vec();
453 let [ty] = &*primitives else {
454 panic!("expected bool; got `{primitives:?}`");
455 };
456 let p = CodegenPrimitive::new(ty);
457 let actual: syn::Type = parse_quote!(#p);
458 let expected: syn::Type = parse_quote!(bool);
459 assert_eq!(actual, expected);
460 }
461
462 #[test]
463 fn test_codegen_primitive_datetime_default_rfc3339() {
464 let doc = Document::from_yaml(indoc::indoc! {"
465 openapi: 3.0.0
466 info:
467 title: Test
468 version: 1.0.0
469 paths: {}
470 components:
471 schemas:
472 Test:
473 type: object
474 required: [value]
475 properties:
476 value:
477 type: string
478 format: date-time
479 "})
480 .unwrap();
481 let arena = Arena::new();
482 let spec = Spec::from_doc(&arena, &doc).unwrap();
483 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
485 let primitives = graph.primitives().collect_vec();
486 let [ty] = &*primitives else {
487 panic!("expected datetime; got `{primitives:?}`");
488 };
489 let p = CodegenPrimitive::new(ty);
490 let actual: syn::Type = parse_quote!(#p);
491 let expected: syn::Type =
492 parse_quote!(::ploidy_util::chrono::DateTime<::ploidy_util::chrono::Utc>);
493 assert_eq!(actual, expected);
494 }
495
496 #[test]
497 fn test_codegen_primitive_datetime_unix_milliseconds() {
498 let doc = Document::from_yaml(indoc::indoc! {"
499 openapi: 3.0.0
500 info:
501 title: Test
502 version: 1.0.0
503 paths: {}
504 components:
505 schemas:
506 Test:
507 type: object
508 required: [value]
509 properties:
510 value:
511 type: string
512 format: date-time
513 "})
514 .unwrap();
515 let arena = Arena::new();
516 let spec = Spec::from_doc(&arena, &doc).unwrap();
517 let graph = CodegenGraph::with_config(
518 RawGraph::new(&arena, &spec).cook(),
519 &CodegenConfig {
520 date_time_format: DateTimeFormat::UnixMilliseconds,
521 },
522 );
523 let primitives = graph.primitives().collect_vec();
524 let [ty] = &*primitives else {
525 panic!("expected datetime; got `{primitives:?}`");
526 };
527 let p = CodegenPrimitive::new(ty);
528 let actual: syn::Type = parse_quote!(#p);
529 let expected: syn::Type = parse_quote!(::ploidy_util::date_time::UnixMilliseconds);
530 assert_eq!(actual, expected);
531 }
532
533 #[test]
534 fn test_codegen_primitive_datetime_unix_seconds() {
535 let doc = Document::from_yaml(indoc::indoc! {"
536 openapi: 3.0.0
537 info:
538 title: Test
539 version: 1.0.0
540 paths: {}
541 components:
542 schemas:
543 Test:
544 type: object
545 required: [value]
546 properties:
547 value:
548 type: string
549 format: date-time
550 "})
551 .unwrap();
552 let arena = Arena::new();
553 let spec = Spec::from_doc(&arena, &doc).unwrap();
554 let graph = CodegenGraph::with_config(
555 RawGraph::new(&arena, &spec).cook(),
556 &CodegenConfig {
557 date_time_format: DateTimeFormat::UnixSeconds,
558 },
559 );
560 let primitives = graph.primitives().collect_vec();
561 let [ty] = &*primitives else {
562 panic!("expected datetime; got `{primitives:?}`");
563 };
564 let p = CodegenPrimitive::new(ty);
565 let actual: syn::Type = parse_quote!(#p);
566 let expected: syn::Type = parse_quote!(::ploidy_util::date_time::UnixSeconds);
567 assert_eq!(actual, expected);
568 }
569
570 #[test]
571 fn test_codegen_primitive_datetime_unix_microseconds() {
572 let doc = Document::from_yaml(indoc::indoc! {"
573 openapi: 3.0.0
574 info:
575 title: Test
576 version: 1.0.0
577 paths: {}
578 components:
579 schemas:
580 Test:
581 type: object
582 required: [value]
583 properties:
584 value:
585 type: string
586 format: date-time
587 "})
588 .unwrap();
589 let arena = Arena::new();
590 let spec = Spec::from_doc(&arena, &doc).unwrap();
591 let graph = CodegenGraph::with_config(
592 RawGraph::new(&arena, &spec).cook(),
593 &CodegenConfig {
594 date_time_format: DateTimeFormat::UnixMicroseconds,
595 },
596 );
597 let primitives = graph.primitives().collect_vec();
598 let [ty] = &*primitives else {
599 panic!("expected datetime; got `{primitives:?}`");
600 };
601 let p = CodegenPrimitive::new(ty);
602 let actual: syn::Type = parse_quote!(#p);
603 let expected: syn::Type = parse_quote!(::ploidy_util::date_time::UnixMicroseconds);
604 assert_eq!(actual, expected);
605 }
606
607 #[test]
608 fn test_codegen_primitive_datetime_unix_nanoseconds() {
609 let doc = Document::from_yaml(indoc::indoc! {"
610 openapi: 3.0.0
611 info:
612 title: Test
613 version: 1.0.0
614 paths: {}
615 components:
616 schemas:
617 Test:
618 type: object
619 required: [value]
620 properties:
621 value:
622 type: string
623 format: date-time
624 "})
625 .unwrap();
626 let arena = Arena::new();
627 let spec = Spec::from_doc(&arena, &doc).unwrap();
628 let graph = CodegenGraph::with_config(
629 RawGraph::new(&arena, &spec).cook(),
630 &CodegenConfig {
631 date_time_format: DateTimeFormat::UnixNanoseconds,
632 },
633 );
634 let primitives = graph.primitives().collect_vec();
635 let [ty] = &*primitives else {
636 panic!("expected datetime; got `{primitives:?}`");
637 };
638 let p = CodegenPrimitive::new(ty);
639 let actual: syn::Type = parse_quote!(#p);
640 let expected: syn::Type = parse_quote!(::ploidy_util::date_time::UnixNanoseconds);
641 assert_eq!(actual, expected);
642 }
643
644 #[test]
645 fn test_codegen_primitive_date() {
646 let doc = Document::from_yaml(indoc::indoc! {"
647 openapi: 3.0.0
648 info:
649 title: Test
650 version: 1.0.0
651 paths: {}
652 components:
653 schemas:
654 Test:
655 type: object
656 required: [value]
657 properties:
658 value:
659 type: string
660 format: date
661 "})
662 .unwrap();
663 let arena = Arena::new();
664 let spec = Spec::from_doc(&arena, &doc).unwrap();
665 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
666 let primitives = graph.primitives().collect_vec();
667 let [ty] = &*primitives else {
668 panic!("expected date; got `{primitives:?}`");
669 };
670 let p = CodegenPrimitive::new(ty);
671 let actual: syn::Type = parse_quote!(#p);
672 let expected: syn::Type = parse_quote!(::ploidy_util::chrono::NaiveDate);
673 assert_eq!(actual, expected);
674 }
675
676 #[test]
677 fn test_codegen_primitive_url() {
678 let doc = Document::from_yaml(indoc::indoc! {"
679 openapi: 3.0.0
680 info:
681 title: Test
682 version: 1.0.0
683 paths: {}
684 components:
685 schemas:
686 Test:
687 type: object
688 required: [value]
689 properties:
690 value:
691 type: string
692 format: uri
693 "})
694 .unwrap();
695 let arena = Arena::new();
696 let spec = Spec::from_doc(&arena, &doc).unwrap();
697 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
698 let primitives = graph.primitives().collect_vec();
699 let [ty] = &*primitives else {
700 panic!("expected url; got `{primitives:?}`");
701 };
702 let p = CodegenPrimitive::new(ty);
703 let actual: syn::Type = parse_quote!(#p);
704 let expected: syn::Type = parse_quote!(::ploidy_util::url::Url);
705 assert_eq!(actual, expected);
706 }
707
708 #[test]
709 fn test_codegen_primitive_uuid() {
710 let doc = Document::from_yaml(indoc::indoc! {"
711 openapi: 3.0.0
712 info:
713 title: Test
714 version: 1.0.0
715 paths: {}
716 components:
717 schemas:
718 Test:
719 type: object
720 required: [value]
721 properties:
722 value:
723 type: string
724 format: uuid
725 "})
726 .unwrap();
727 let arena = Arena::new();
728 let spec = Spec::from_doc(&arena, &doc).unwrap();
729 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
730 let primitives = graph.primitives().collect_vec();
731 let [ty] = &*primitives else {
732 panic!("expected uuid; got `{primitives:?}`");
733 };
734 let p = CodegenPrimitive::new(ty);
735 let actual: syn::Type = parse_quote!(#p);
736 let expected: syn::Type = parse_quote!(::ploidy_util::uuid::Uuid);
737 assert_eq!(actual, expected);
738 }
739
740 #[test]
741 fn test_codegen_primitive_bytes() {
742 let doc = Document::from_yaml(indoc::indoc! {"
743 openapi: 3.0.0
744 info:
745 title: Test
746 version: 1.0.0
747 paths: {}
748 components:
749 schemas:
750 Test:
751 type: object
752 required: [value]
753 properties:
754 value:
755 type: string
756 format: byte
757 "})
758 .unwrap();
759 let arena = Arena::new();
760 let spec = Spec::from_doc(&arena, &doc).unwrap();
761 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
762 let primitives = graph.primitives().collect_vec();
763 let [ty] = &*primitives else {
764 panic!("expected bytes; got `{primitives:?}`");
765 };
766 let p = CodegenPrimitive::new(ty);
767 let actual: syn::Type = parse_quote!(#p);
768 let expected: syn::Type = parse_quote!(::ploidy_util::binary::Base64);
769 assert_eq!(actual, expected);
770 }
771
772 #[test]
773 fn test_codegen_primitive_binary() {
774 let doc = Document::from_yaml(indoc::indoc! {"
775 openapi: 3.0.0
776 info:
777 title: Test
778 version: 1.0.0
779 paths: {}
780 components:
781 schemas:
782 Test:
783 type: object
784 required: [value]
785 properties:
786 value:
787 type: string
788 format: binary
789 "})
790 .unwrap();
791 let arena = Arena::new();
792 let spec = Spec::from_doc(&arena, &doc).unwrap();
793 let graph = CodegenGraph::new(RawGraph::new(&arena, &spec).cook());
794 let primitives = graph.primitives().collect_vec();
795 let [ty] = &*primitives else {
796 panic!("expected binary; got `{primitives:?}`");
797 };
798 let p = CodegenPrimitive::new(ty);
799 let actual: syn::Type = parse_quote!(#p);
800 let expected: syn::Type = parse_quote!(::ploidy_util::serde_bytes::ByteBuf);
801 assert_eq!(actual, expected);
802 }
803}