1use crate::analysis::analysed_type::{
16 case, list, option, result, result_err, result_ok, str, tuple, u32, unit_case, variant,
17};
18use crate::analysis::{
19 analysed_type, AnalysedResourceId, AnalysedResourceMode, AnalysedType, NameTypePair, TypeEnum,
20 TypeFlags,
21};
22use crate::golem_rpc_0_2_x::types::NamedWitTypeNode;
23use crate::{NodeIndex, ResourceMode, RpcError, Value, WitNode, WitType, WitTypeNode, WitValue};
24use std::collections::{BTreeMap, BTreeSet, HashMap};
25use std::ops::Bound;
26use std::time::{Duration, Instant};
27use uuid::Uuid;
28
29#[derive(Clone, Debug, PartialEq)]
30#[cfg_attr(feature = "host", derive(::bincode::Encode, ::bincode::Decode))]
31pub struct ValueAndType {
32 pub value: Value,
33 pub typ: AnalysedType,
34}
35
36#[cfg(feature = "host")]
37impl std::fmt::Display for ValueAndType {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 write!(
40 f,
41 "{}",
42 crate::text::print_value_and_type(self).unwrap_or("<unprintable>".to_string())
43 )
44 }
45}
46
47impl ValueAndType {
48 pub fn new(value: Value, typ: AnalysedType) -> Self {
49 Self { value, typ }
50 }
51
52 pub fn into_list_items(self) -> Option<Vec<ValueAndType>> {
53 match (self.value, self.typ) {
54 (Value::List(items), AnalysedType::List(item_type)) => Some(
55 items
56 .into_iter()
57 .map(|item| ValueAndType::new(item, (*item_type.inner).clone()))
58 .collect(),
59 ),
60 _ => None,
61 }
62 }
63}
64
65impl From<ValueAndType> for Value {
66 fn from(value_and_type: ValueAndType) -> Self {
67 value_and_type.value
68 }
69}
70
71impl From<ValueAndType> for AnalysedType {
72 fn from(value_and_type: ValueAndType) -> Self {
73 value_and_type.typ
74 }
75}
76
77#[cfg(feature = "host")]
78impl From<ValueAndType> for WitValue {
79 fn from(value_and_type: ValueAndType) -> Self {
80 value_and_type.value.into()
81 }
82}
83
84#[cfg(feature = "host")]
85impl From<ValueAndType> for WitType {
86 fn from(value_and_type: ValueAndType) -> Self {
87 value_and_type.typ.into()
88 }
89}
90
91pub trait IntoValue {
93 fn into_value(self) -> Value;
94 fn get_type() -> AnalysedType;
95}
96
97pub trait IntoValueAndType {
98 fn into_value_and_type(self) -> ValueAndType;
99}
100
101impl<T: IntoValue + Sized> IntoValueAndType for T {
102 fn into_value_and_type(self) -> ValueAndType {
103 ValueAndType::new(self.into_value(), Self::get_type())
104 }
105}
106
107impl IntoValue for u8 {
108 fn into_value(self) -> Value {
109 Value::U8(self)
110 }
111
112 fn get_type() -> AnalysedType {
113 analysed_type::u8()
114 }
115}
116
117impl IntoValue for u16 {
118 fn into_value(self) -> Value {
119 Value::U16(self)
120 }
121
122 fn get_type() -> AnalysedType {
123 analysed_type::u16()
124 }
125}
126
127impl IntoValue for u32 {
128 fn into_value(self) -> Value {
129 Value::U32(self)
130 }
131
132 fn get_type() -> AnalysedType {
133 u32()
134 }
135}
136
137impl IntoValue for u64 {
138 fn into_value(self) -> Value {
139 Value::U64(self)
140 }
141
142 fn get_type() -> AnalysedType {
143 analysed_type::u64()
144 }
145}
146
147impl IntoValue for i8 {
148 fn into_value(self) -> Value {
149 Value::S8(self)
150 }
151
152 fn get_type() -> AnalysedType {
153 analysed_type::s8()
154 }
155}
156
157impl IntoValue for i16 {
158 fn into_value(self) -> Value {
159 Value::S16(self)
160 }
161
162 fn get_type() -> AnalysedType {
163 analysed_type::s16()
164 }
165}
166
167impl IntoValue for i32 {
168 fn into_value(self) -> Value {
169 Value::S32(self)
170 }
171
172 fn get_type() -> AnalysedType {
173 analysed_type::s32()
174 }
175}
176
177impl IntoValue for i64 {
178 fn into_value(self) -> Value {
179 Value::S64(self)
180 }
181
182 fn get_type() -> AnalysedType {
183 analysed_type::s64()
184 }
185}
186
187impl IntoValue for f32 {
188 fn into_value(self) -> Value {
189 Value::F32(self)
190 }
191
192 fn get_type() -> AnalysedType {
193 analysed_type::f32()
194 }
195}
196
197impl IntoValue for f64 {
198 fn into_value(self) -> Value {
199 Value::F64(self)
200 }
201
202 fn get_type() -> AnalysedType {
203 analysed_type::f64()
204 }
205}
206
207impl IntoValue for bool {
208 fn into_value(self) -> Value {
209 Value::Bool(self)
210 }
211
212 fn get_type() -> AnalysedType {
213 analysed_type::bool()
214 }
215}
216
217impl IntoValue for char {
218 fn into_value(self) -> Value {
219 Value::Char(self)
220 }
221
222 fn get_type() -> AnalysedType {
223 analysed_type::chr()
224 }
225}
226
227impl IntoValue for String {
228 fn into_value(self) -> Value {
229 Value::String(self)
230 }
231
232 fn get_type() -> AnalysedType {
233 str()
234 }
235}
236
237impl IntoValue for &str {
238 fn into_value(self) -> Value {
239 Value::String(self.to_string())
240 }
241
242 fn get_type() -> AnalysedType {
243 str()
244 }
245}
246
247impl<S: IntoValue, E: IntoValue> IntoValue for Result<S, E> {
248 fn into_value(self) -> Value {
249 match self {
250 Ok(s) => Value::Result(Ok(Some(Box::new(s.into_value())))),
251 Err(e) => Value::Result(Err(Some(Box::new(e.into_value())))),
252 }
253 }
254
255 fn get_type() -> AnalysedType {
256 result(S::get_type(), E::get_type())
257 }
258}
259
260impl<E: IntoValue> IntoValue for Result<(), E> {
261 fn into_value(self) -> Value {
262 match self {
263 Ok(_) => Value::Result(Ok(None)),
264 Err(e) => Value::Result(Err(Some(Box::new(e.into_value())))),
265 }
266 }
267
268 fn get_type() -> AnalysedType {
269 result_err(E::get_type())
270 }
271}
272
273impl<S: IntoValue> IntoValue for Result<S, ()> {
274 fn into_value(self) -> Value {
275 match self {
276 Ok(s) => Value::Result(Ok(Some(Box::new(s.into_value())))),
277 Err(_) => Value::Result(Err(None)),
278 }
279 }
280
281 fn get_type() -> AnalysedType {
282 result_ok(S::get_type())
283 }
284}
285
286impl<T: IntoValue> IntoValue for Box<T> {
287 fn into_value(self) -> Value {
288 (*self).into_value()
289 }
290
291 fn get_type() -> AnalysedType {
292 T::get_type()
293 }
294}
295
296impl<T: IntoValue> IntoValue for Option<T> {
297 fn into_value(self) -> Value {
298 match self {
299 Some(t) => Value::Option(Some(Box::new(t.into_value()))),
300 None => Value::Option(None),
301 }
302 }
303
304 fn get_type() -> AnalysedType {
305 option(T::get_type())
306 }
307}
308
309impl<T: IntoValue> IntoValue for Bound<T> {
310 fn into_value(self) -> Value {
311 match self {
312 Bound::Included(t) => Value::Variant {
313 case_idx: 0,
314 case_value: Some(Box::new(t.into_value())),
315 },
316 Bound::Excluded(t) => Value::Variant {
317 case_idx: 1,
318 case_value: Some(Box::new(t.into_value())),
319 },
320 Bound::Unbounded => Value::Variant {
321 case_idx: 2,
322 case_value: None,
323 },
324 }
325 }
326
327 fn get_type() -> AnalysedType {
328 variant(vec![
329 case("included", T::get_type()),
330 case("excluded", T::get_type()),
331 unit_case("unbounded"),
332 ])
333 }
334}
335
336impl<T: IntoValue> IntoValue for Vec<T> {
337 fn into_value(self) -> Value {
338 Value::List(self.into_iter().map(IntoValue::into_value).collect())
339 }
340
341 fn get_type() -> AnalysedType {
342 list(T::get_type())
343 }
344}
345
346impl<A: IntoValue, B: IntoValue> IntoValue for (A, B) {
347 fn into_value(self) -> Value {
348 Value::Tuple(vec![self.0.into_value(), self.1.into_value()])
349 }
350
351 fn get_type() -> AnalysedType {
352 tuple(vec![A::get_type(), B::get_type()])
353 }
354}
355
356impl<A: IntoValue, B: IntoValue, C: IntoValue> IntoValue for (A, B, C) {
357 fn into_value(self) -> Value {
358 Value::Tuple(vec![
359 self.0.into_value(),
360 self.1.into_value(),
361 self.2.into_value(),
362 ])
363 }
364
365 fn get_type() -> AnalysedType {
366 tuple(vec![A::get_type(), B::get_type(), C::get_type()])
367 }
368}
369
370impl<K: IntoValue, V: IntoValue> IntoValue for HashMap<K, V> {
371 fn into_value(self) -> Value {
372 Value::List(
373 self.into_iter()
374 .map(|(k, v)| Value::Tuple(vec![k.into_value(), v.into_value()]))
375 .collect(),
376 )
377 }
378
379 fn get_type() -> AnalysedType {
380 list(tuple(vec![K::get_type(), V::get_type()]))
381 }
382}
383
384impl<K: IntoValue, V: IntoValue> IntoValue for BTreeMap<K, V> {
385 fn into_value(self) -> Value {
386 Value::List(
387 self.into_iter()
388 .map(|(k, v)| Value::Tuple(vec![k.into_value(), v.into_value()]))
389 .collect(),
390 )
391 }
392
393 fn get_type() -> AnalysedType {
394 list(tuple(vec![K::get_type(), V::get_type()]))
395 }
396}
397
398impl<T: IntoValue> IntoValue for BTreeSet<T> {
399 fn into_value(self) -> Value {
400 Value::List(self.into_iter().map(IntoValue::into_value).collect())
401 }
402
403 fn get_type() -> AnalysedType {
404 list(T::get_type())
405 }
406}
407
408impl IntoValue for Uuid {
409 fn into_value(self) -> Value {
410 Value::String(self.to_string())
411 }
412
413 fn get_type() -> AnalysedType {
414 analysed_type::str()
415 }
416}
417
418pub struct Record<K: AsRef<str>>(pub Vec<(K, ValueAndType)>);
420
421impl<K: AsRef<str>> IntoValueAndType for Record<K> {
422 fn into_value_and_type(self) -> ValueAndType {
423 let mut field_types = Vec::<NameTypePair>::with_capacity(self.0.len());
424 let mut field_values = Vec::<Value>::with_capacity(self.0.len());
425
426 for (field_name, value_and_type) in self.0 {
427 field_types.push(NameTypePair {
428 name: field_name.as_ref().to_string(),
429 typ: value_and_type.typ,
430 });
431 field_values.push(value_and_type.value);
432 }
433
434 ValueAndType {
435 value: Value::Record(field_values),
436 typ: analysed_type::record(field_types),
437 }
438 }
439}
440
441#[cfg(feature = "host")]
442impl IntoValue for crate::WitValue {
443 fn into_value(self) -> Value {
444 Value::Record(vec![self.nodes.into_value()])
448 }
449
450 fn get_type() -> AnalysedType {
451 analysed_type::record(vec![analysed_type::field(
452 "nodes",
453 list(crate::WitNode::get_type()),
454 )])
455 }
456}
457
458#[cfg(feature = "host")]
459impl IntoValue for WitNode {
460 fn into_value(self) -> Value {
461 use crate::WitNode;
462
463 match self {
464 WitNode::RecordValue(indices) => Value::Variant {
465 case_idx: 0,
466 case_value: Some(Box::new(indices.into_value())),
467 },
468 WitNode::VariantValue((idx, value)) => Value::Variant {
469 case_idx: 1,
470 case_value: Some(Box::new(Value::Tuple(vec![
471 idx.into_value(),
472 value
473 .map(|idx| Value::Option(Some(Box::new(idx.into_value()))))
474 .unwrap_or(Value::Option(None)),
475 ]))),
476 },
477 WitNode::EnumValue(idx) => Value::Variant {
478 case_idx: 2,
479 case_value: Some(Box::new(idx.into_value())),
480 },
481 WitNode::FlagsValue(flags) => Value::Variant {
482 case_idx: 3,
483 case_value: Some(Box::new(flags.into_value())),
484 },
485 WitNode::TupleValue(indices) => Value::Variant {
486 case_idx: 4,
487 case_value: Some(Box::new(indices.into_value())),
488 },
489 WitNode::ListValue(indices) => Value::Variant {
490 case_idx: 5,
491 case_value: Some(Box::new(indices.into_value())),
492 },
493 WitNode::OptionValue(index) => Value::Variant {
494 case_idx: 6,
495 case_value: Some(Box::new(index.into_value())),
496 },
497 WitNode::ResultValue(result) => Value::Variant {
498 case_idx: 7,
499 case_value: Some(Box::new(result.into_value())),
500 },
501 WitNode::PrimU8(value) => Value::Variant {
502 case_idx: 8,
503 case_value: Some(Box::new(value.into_value())),
504 },
505 WitNode::PrimU16(value) => Value::Variant {
506 case_idx: 9,
507 case_value: Some(Box::new(value.into_value())),
508 },
509 WitNode::PrimU32(value) => Value::Variant {
510 case_idx: 10,
511 case_value: Some(Box::new(value.into_value())),
512 },
513 WitNode::PrimU64(value) => Value::Variant {
514 case_idx: 11,
515 case_value: Some(Box::new(value.into_value())),
516 },
517 WitNode::PrimS8(value) => Value::Variant {
518 case_idx: 12,
519 case_value: Some(Box::new(value.into_value())),
520 },
521 WitNode::PrimS16(value) => Value::Variant {
522 case_idx: 13,
523 case_value: Some(Box::new(value.into_value())),
524 },
525 WitNode::PrimS32(value) => Value::Variant {
526 case_idx: 14,
527 case_value: Some(Box::new(value.into_value())),
528 },
529 WitNode::PrimS64(value) => Value::Variant {
530 case_idx: 15,
531 case_value: Some(Box::new(value.into_value())),
532 },
533 WitNode::PrimFloat32(value) => Value::Variant {
534 case_idx: 16,
535 case_value: Some(Box::new(value.into_value())),
536 },
537 WitNode::PrimFloat64(value) => Value::Variant {
538 case_idx: 17,
539 case_value: Some(Box::new(value.into_value())),
540 },
541 WitNode::PrimChar(value) => Value::Variant {
542 case_idx: 18,
543 case_value: Some(Box::new(value.into_value())),
544 },
545 WitNode::PrimBool(value) => Value::Variant {
546 case_idx: 19,
547 case_value: Some(Box::new(value.into_value())),
548 },
549 WitNode::PrimString(value) => Value::Variant {
550 case_idx: 20,
551 case_value: Some(Box::new(value.into_value())),
552 },
553 WitNode::Handle((uri, resource_id)) => Value::Variant {
554 case_idx: 21,
555 case_value: Some(Box::new(Value::Tuple(vec![
556 uri.into_value(),
557 resource_id.into_value(),
558 ]))),
559 },
560 }
561 }
562
563 fn get_type() -> AnalysedType {
564 use crate::NodeIndex;
565 use analysed_type::{case, variant};
566
567 variant(vec![
568 case("record-value", list(NodeIndex::get_type())),
569 case(
570 "variant-value",
571 tuple(vec![analysed_type::u32(), option(NodeIndex::get_type())]),
572 ),
573 case("enum-value", analysed_type::u32()),
574 case("flags-value", list(analysed_type::bool())),
575 case("tuple-value", list(NodeIndex::get_type())),
576 case("list-value", list(NodeIndex::get_type())),
577 case("option-value", option(NodeIndex::get_type())),
578 case(
579 "result-value",
580 result(option(NodeIndex::get_type()), option(NodeIndex::get_type())),
581 ),
582 case("prim-u8", analysed_type::u8()),
583 case("prim-u16", analysed_type::u16()),
584 case("prim-u32", analysed_type::u32()),
585 case("prim-u64", analysed_type::u64()),
586 case("prim-s8", analysed_type::s8()),
587 case("prim-s16", analysed_type::s16()),
588 case("prim-s32", analysed_type::s32()),
589 case("prim-s64", analysed_type::s64()),
590 case("prim-float32", analysed_type::f32()),
591 case("prim-float64", analysed_type::f64()),
592 case("prim-char", analysed_type::chr()),
593 case("prim-bool", analysed_type::bool()),
594 case("prim-string", analysed_type::str()),
595 case(
596 "handle",
597 tuple(vec![crate::Uri::get_type(), analysed_type::u64()]),
598 ),
599 ])
600 }
601}
602
603#[cfg(feature = "host")]
604impl IntoValue for crate::Uri {
605 fn into_value(self) -> Value {
606 Value::Record(vec![Value::String(self.value)])
607 }
608
609 fn get_type() -> AnalysedType {
610 analysed_type::record(vec![analysed_type::field("value", analysed_type::str())])
611 }
612}
613
614#[cfg(feature = "host")]
615impl IntoValue for WitType {
616 fn into_value(self) -> Value {
617 Value::Record(vec![self.nodes.into_value()])
618 }
619
620 fn get_type() -> AnalysedType {
621 analysed_type::record(vec![analysed_type::field(
622 "nodes",
623 list(NamedWitTypeNode::get_type()),
624 )])
625 }
626}
627
628#[cfg(feature = "host")]
629impl IntoValue for NamedWitTypeNode {
630 fn into_value(self) -> Value {
631 Value::Record(vec![
632 self.name.into_value(),
633 self.owner.into_value(),
634 self.type_.into_value(),
635 ])
636 }
637
638 fn get_type() -> AnalysedType {
639 analysed_type::record(vec![
640 analysed_type::field("name", option(analysed_type::str())),
641 analysed_type::field("owner", option(analysed_type::str())),
642 analysed_type::field("type", WitTypeNode::get_type()),
643 ])
644 }
645}
646
647#[cfg(feature = "host")]
648impl IntoValue for WitTypeNode {
649 fn into_value(self) -> Value {
650 match self {
651 WitTypeNode::RecordType(field_types) => Value::Variant {
652 case_idx: 0,
653 case_value: Some(Box::new(field_types.into_value())),
654 },
655 WitTypeNode::VariantType(case_types) => Value::Variant {
656 case_idx: 1,
657 case_value: Some(Box::new(case_types.into_value())),
658 },
659 WitTypeNode::EnumType(names) => Value::Variant {
660 case_idx: 2,
661 case_value: Some(Box::new(names.into_value())),
662 },
663 WitTypeNode::FlagsType(names) => Value::Variant {
664 case_idx: 3,
665 case_value: Some(Box::new(names.into_value())),
666 },
667 WitTypeNode::TupleType(types) => Value::Variant {
668 case_idx: 4,
669 case_value: Some(Box::new(types.into_value())),
670 },
671 WitTypeNode::ListType(elem) => Value::Variant {
672 case_idx: 5,
673 case_value: Some(Box::new(elem.into_value())),
674 },
675 WitTypeNode::OptionType(elem) => Value::Variant {
676 case_idx: 6,
677 case_value: Some(Box::new(elem.into_value())),
678 },
679 WitTypeNode::ResultType((ok, err)) => Value::Variant {
680 case_idx: 7,
681 case_value: Some(Box::new((ok, err).into_value())),
682 },
683 WitTypeNode::PrimU8Type => Value::Variant {
684 case_idx: 8,
685 case_value: None,
686 },
687 WitTypeNode::PrimU16Type => Value::Variant {
688 case_idx: 9,
689 case_value: None,
690 },
691 WitTypeNode::PrimU32Type => Value::Variant {
692 case_idx: 10,
693 case_value: None,
694 },
695 WitTypeNode::PrimU64Type => Value::Variant {
696 case_idx: 11,
697 case_value: None,
698 },
699 WitTypeNode::PrimS8Type => Value::Variant {
700 case_idx: 12,
701 case_value: None,
702 },
703 WitTypeNode::PrimS16Type => Value::Variant {
704 case_idx: 13,
705 case_value: None,
706 },
707 WitTypeNode::PrimS32Type => Value::Variant {
708 case_idx: 14,
709 case_value: None,
710 },
711 WitTypeNode::PrimS64Type => Value::Variant {
712 case_idx: 15,
713 case_value: None,
714 },
715 WitTypeNode::PrimF32Type => Value::Variant {
716 case_idx: 16,
717 case_value: None,
718 },
719 WitTypeNode::PrimF64Type => Value::Variant {
720 case_idx: 17,
721 case_value: None,
722 },
723 WitTypeNode::PrimCharType => Value::Variant {
724 case_idx: 18,
725 case_value: None,
726 },
727 WitTypeNode::PrimBoolType => Value::Variant {
728 case_idx: 19,
729 case_value: None,
730 },
731 WitTypeNode::PrimStringType => Value::Variant {
732 case_idx: 20,
733 case_value: None,
734 },
735 WitTypeNode::HandleType(handle) => Value::Variant {
736 case_idx: 17,
737 case_value: Some(Box::new(handle.into_value())),
738 },
739 }
740 }
741
742 fn get_type() -> AnalysedType {
743 variant(vec![
744 case(
745 "record-type",
746 list(tuple(vec![str(), NodeIndex::get_type()])),
747 ),
748 case(
749 "variant-type",
750 list(tuple(vec![str(), option(NodeIndex::get_type())])),
751 ),
752 case("enum-type", list(str())),
753 case("flags-type", list(str())),
754 case("tuple-type", list(NodeIndex::get_type())),
755 case("list-type", NodeIndex::get_type()),
756 case("option-type", NodeIndex::get_type()),
757 case(
758 "result-type",
759 tuple(vec![
760 option(NodeIndex::get_type()),
761 option(NodeIndex::get_type()),
762 ]),
763 ),
764 unit_case("prim-u8-type"),
765 unit_case("prim-u16-type"),
766 unit_case("prim-u32-type"),
767 unit_case("prim-u64-type"),
768 unit_case("prim-s8-type"),
769 unit_case("prim-s16-type"),
770 unit_case("prim-s32-type"),
771 unit_case("prim-s64-type"),
772 unit_case("prim-f32-type"),
773 unit_case("prim-f64-type"),
774 unit_case("prim-char-type"),
775 unit_case("prim-bool-type"),
776 unit_case("prim-string-type"),
777 case(
778 "handle-type",
779 tuple(vec![analysed_type::u64(), ResourceMode::get_type()]),
780 ),
781 ])
782 }
783}
784
785impl IntoValue for Instant {
786 fn into_value(self) -> Value {
787 Value::U64(self.elapsed().as_nanos() as u64)
788 }
789
790 fn get_type() -> AnalysedType {
791 analysed_type::u64()
792 }
793}
794
795impl IntoValue for Duration {
796 fn into_value(self) -> Value {
797 Value::U64(self.as_nanos() as u64)
798 }
799
800 fn get_type() -> AnalysedType {
801 analysed_type::u64()
802 }
803}
804
805#[cfg(feature = "host")]
806impl IntoValue for crate::ResourceMode {
807 fn into_value(self) -> Value {
808 match self {
809 ResourceMode::Owned => Value::Enum(0),
810 ResourceMode::Borrowed => Value::Enum(1),
811 }
812 }
813
814 fn get_type() -> AnalysedType {
815 analysed_type::r#enum(&["owned", "borrowed"])
816 }
817}
818
819#[cfg(feature = "host")]
820impl IntoValue for crate::RpcError {
821 fn into_value(self) -> Value {
822 match self {
823 RpcError::ProtocolError(value) => Value::Variant {
824 case_idx: 0,
825 case_value: Some(Box::new(Value::String(value))),
826 },
827 RpcError::Denied(value) => Value::Variant {
828 case_idx: 1,
829 case_value: Some(Box::new(Value::String(value))),
830 },
831 RpcError::NotFound(value) => Value::Variant {
832 case_idx: 2,
833 case_value: Some(Box::new(Value::String(value))),
834 },
835 RpcError::RemoteInternalError(value) => Value::Variant {
836 case_idx: 3,
837 case_value: Some(Box::new(Value::String(value))),
838 },
839 }
840 }
841
842 fn get_type() -> AnalysedType {
843 use analysed_type::case;
844
845 variant(vec![
846 case("protocol-error", analysed_type::str()),
847 case("denied", analysed_type::str()),
848 case("not-found", analysed_type::str()),
849 case("remote-internal-error", analysed_type::str()),
850 ])
851 }
852}
853
854#[cfg(feature = "host")]
855impl IntoValue for ValueAndType {
856 fn into_value(self) -> Value {
857 let wit_value: WitValue = self.value.into();
858 let wit_type: WitType = self.typ.into();
859 Value::Record(vec![wit_value.into_value(), wit_type.into_value()])
860 }
861
862 fn get_type() -> AnalysedType {
863 analysed_type::record(vec![
864 analysed_type::field("value", WitValue::get_type()),
865 analysed_type::field("type", WitType::get_type()),
866 ])
867 }
868}
869
870#[cfg(feature = "host")]
871impl IntoValue for Value {
872 fn into_value(self) -> Value {
873 let wit_value: WitValue = self.into();
874 wit_value.into_value()
875 }
876
877 fn get_type() -> AnalysedType {
878 WitValue::get_type()
879 }
880}
881
882#[cfg(feature = "host")]
883impl IntoValue for AnalysedType {
884 fn into_value(self) -> Value {
885 let wit_type: WitType = self.into();
886 wit_type.into_value()
887 }
888
889 fn get_type() -> AnalysedType {
890 WitType::get_type()
891 }
892}
893
894impl From<WitType> for AnalysedType {
895 fn from(value: WitType) -> Self {
896 assert!(!value.nodes.is_empty());
897 build_tree(&value.nodes[0], &value.nodes)
898 }
899}
900
901fn build_tree(node: &NamedWitTypeNode, nodes: &[NamedWitTypeNode]) -> AnalysedType {
902 match &node.type_ {
903 WitTypeNode::RecordType(fields) => {
904 let fields = fields
905 .iter()
906 .map(|(name, idx)| {
907 let field_type = build_tree(&nodes[*idx as usize], nodes);
908 analysed_type::field(name, field_type)
909 })
910 .collect();
911 analysed_type::record(fields).with_optional_name(node.name.clone())
912 }
913 WitTypeNode::VariantType(cases) => {
914 let cases = cases
915 .iter()
916 .map(|(name, idx)| match idx {
917 Some(idx) => {
918 let case_type = build_tree(&nodes[*idx as usize], nodes);
919 analysed_type::case(name, case_type)
920 }
921 None => analysed_type::unit_case(name),
922 })
923 .collect();
924 variant(cases).with_optional_name(node.name.clone())
925 }
926 WitTypeNode::EnumType(names) => AnalysedType::Enum(TypeEnum {
927 cases: names.clone(),
928 name: node.name.clone(),
929 owner: node.owner.clone(),
930 }),
931 WitTypeNode::FlagsType(names) => AnalysedType::Flags(TypeFlags {
932 names: names.clone(),
933 name: node.name.clone(),
934 owner: node.owner.clone(),
935 }),
936 WitTypeNode::TupleType(types) => {
937 let types = types
938 .iter()
939 .map(|idx| build_tree(&nodes[*idx as usize], nodes))
940 .collect();
941 tuple(types).with_optional_name(node.name.clone())
942 }
943 WitTypeNode::ListType(elem_type) => {
944 let elem_type = build_tree(&nodes[*elem_type as usize], nodes);
945 list(elem_type).with_optional_name(node.name.clone())
946 }
947 WitTypeNode::OptionType(inner_type) => {
948 let inner_type = build_tree(&nodes[*inner_type as usize], nodes);
949 option(inner_type).with_optional_name(node.name.clone())
950 }
951 WitTypeNode::ResultType((ok_type, err_type)) => match (ok_type, err_type) {
952 (Some(ok_type), Some(err_type)) => {
953 let ok_type = build_tree(&nodes[*ok_type as usize], nodes);
954 let err_type = build_tree(&nodes[*err_type as usize], nodes);
955 result(ok_type, err_type).with_optional_name(node.name.clone())
956 }
957 (None, Some(err_type)) => {
958 let err_type = build_tree(&nodes[*err_type as usize], nodes);
959 result_err(err_type).with_optional_name(node.name.clone())
960 }
961 (Some(ok_type), None) => {
962 let ok_type = build_tree(&nodes[*ok_type as usize], nodes);
963 result_ok(ok_type).with_optional_name(node.name.clone())
964 }
965 (None, None) => panic!("ResultType with no ok_type or err_type"),
966 },
967 WitTypeNode::PrimU8Type => analysed_type::u8(),
968 WitTypeNode::PrimU16Type => analysed_type::u16(),
969 WitTypeNode::PrimU32Type => analysed_type::u32(),
970 WitTypeNode::PrimU64Type => analysed_type::u64(),
971 WitTypeNode::PrimS8Type => analysed_type::s8(),
972 WitTypeNode::PrimS16Type => analysed_type::s16(),
973 WitTypeNode::PrimS32Type => analysed_type::s32(),
974 WitTypeNode::PrimS64Type => analysed_type::s64(),
975 WitTypeNode::PrimF32Type => analysed_type::f32(),
976 WitTypeNode::PrimF64Type => analysed_type::f64(),
977 WitTypeNode::PrimCharType => analysed_type::chr(),
978 WitTypeNode::PrimBoolType => analysed_type::bool(),
979 WitTypeNode::PrimStringType => analysed_type::str(),
980 WitTypeNode::HandleType((id, mode)) => analysed_type::handle(
981 AnalysedResourceId(*id),
982 match mode {
983 crate::ResourceMode::Owned => AnalysedResourceMode::Owned,
984 crate::ResourceMode::Borrowed => AnalysedResourceMode::Borrowed,
985 },
986 )
987 .with_optional_name(node.name.clone()),
988 }
989}
990
991impl From<AnalysedType> for WitType {
992 fn from(value: AnalysedType) -> Self {
993 let mut builder = WitTypeBuilder::new();
994 builder.add(value);
995 builder.build()
996 }
997}
998
999struct WitTypeBuilder {
1000 nodes: Vec<NamedWitTypeNode>,
1001 mapping: HashMap<AnalysedType, usize>,
1002}
1003
1004impl WitTypeBuilder {
1005 pub fn new() -> Self {
1006 Self {
1007 nodes: Vec::new(),
1008 mapping: HashMap::new(),
1009 }
1010 }
1011
1012 pub fn add(&mut self, typ: AnalysedType) -> usize {
1013 if let Some(idx) = self.mapping.get(&typ) {
1014 *idx
1015 } else {
1016 let idx = self.nodes.len();
1017 self.nodes.push(NamedWitTypeNode {
1018 name: None,
1019 owner: None,
1020 type_: WitTypeNode::PrimBoolType,
1021 }); let name = typ.name().map(|n| n.to_string());
1023 let owner = typ.owner().map(|o| o.to_string());
1024 let node: WitTypeNode = match typ {
1025 AnalysedType::Variant(variant) => {
1026 let mut cases = Vec::new();
1027 for pair in variant.cases {
1028 let case_idx = pair.typ.map(|case| self.add(case) as i32);
1029 cases.push((pair.name, case_idx));
1030 }
1031 WitTypeNode::VariantType(cases)
1032 }
1033 AnalysedType::Result(result) => {
1034 let ok_idx = result.ok.map(|ok| self.add(*ok) as i32);
1035 let err_idx = result.err.map(|err| self.add(*err) as i32);
1036 WitTypeNode::ResultType((ok_idx, err_idx))
1037 }
1038 AnalysedType::Option(option) => {
1039 let inner_idx = self.add(*option.inner) as i32;
1040 WitTypeNode::OptionType(inner_idx)
1041 }
1042 AnalysedType::Enum(enm) => WitTypeNode::EnumType(enm.cases),
1043 AnalysedType::Flags(flags) => WitTypeNode::FlagsType(flags.names),
1044 AnalysedType::Record(record) => {
1045 let mut fields = Vec::new();
1046 for field in record.fields {
1047 fields.push((field.name, self.add(field.typ) as i32));
1048 }
1049 WitTypeNode::RecordType(fields)
1050 }
1051 AnalysedType::Tuple(tuple) => {
1052 let mut indices = Vec::new();
1053 for item in tuple.items {
1054 indices.push(self.add(item) as i32);
1055 }
1056 WitTypeNode::TupleType(indices)
1057 }
1058 AnalysedType::List(lst) => {
1059 let elem_idx = self.add(*lst.inner);
1060 WitTypeNode::ListType(elem_idx as i32)
1061 }
1062 AnalysedType::Str(_) => WitTypeNode::PrimStringType,
1063 AnalysedType::Chr(_) => WitTypeNode::PrimCharType,
1064 AnalysedType::F64(_) => WitTypeNode::PrimF64Type,
1065 AnalysedType::F32(_) => WitTypeNode::PrimF32Type,
1066 AnalysedType::U64(_) => WitTypeNode::PrimU64Type,
1067 AnalysedType::S64(_) => WitTypeNode::PrimS64Type,
1068 AnalysedType::U32(_) => WitTypeNode::PrimU32Type,
1069 AnalysedType::S32(_) => WitTypeNode::PrimS32Type,
1070 AnalysedType::U16(_) => WitTypeNode::PrimU16Type,
1071 AnalysedType::S16(_) => WitTypeNode::PrimS16Type,
1072 AnalysedType::U8(_) => WitTypeNode::PrimU8Type,
1073 AnalysedType::S8(_) => WitTypeNode::PrimS8Type,
1074 AnalysedType::Bool(_) => WitTypeNode::PrimBoolType,
1075 AnalysedType::Handle(handle) => WitTypeNode::HandleType((
1076 handle.resource_id.0,
1077 match handle.mode {
1078 AnalysedResourceMode::Owned => ResourceMode::Owned,
1079 AnalysedResourceMode::Borrowed => ResourceMode::Borrowed,
1080 },
1081 )),
1082 };
1083 self.nodes[idx] = NamedWitTypeNode {
1084 name,
1085 owner,
1086 type_: node,
1087 };
1088 idx
1089 }
1090 }
1091
1092 pub fn build(self) -> WitType {
1093 WitType { nodes: self.nodes }
1094 }
1095}
1096
1097impl From<crate::golem_rpc_0_2_x::types::ValueAndType> for ValueAndType {
1098 fn from(value: crate::golem_rpc_0_2_x::types::ValueAndType) -> Self {
1099 Self {
1100 value: value.value.into(),
1101 typ: value.typ.into(),
1102 }
1103 }
1104}
1105
1106impl From<ValueAndType> for crate::golem_rpc_0_2_x::types::ValueAndType {
1107 fn from(value: ValueAndType) -> Self {
1108 Self {
1109 value: value.value.into(),
1110 typ: value.typ.into(),
1111 }
1112 }
1113}
1114
1115#[cfg(feature = "host")]
1116mod extra_bindings {
1117 use crate::analysis::analysed_type::{bool, list, str};
1118 use crate::analysis::{analysed_type, AnalysedType};
1119 use crate::{IntoValue, IntoValueAndType, Value};
1120 use bigdecimal::BigDecimal;
1121 use bit_vec::BitVec;
1122 use chrono::{Datelike, Offset, Timelike};
1123 use url::Url;
1124
1125 impl IntoValue for BigDecimal {
1126 fn into_value(self) -> Value {
1127 self.to_string().into_value()
1128 }
1129
1130 fn get_type() -> AnalysedType {
1131 str()
1132 }
1133 }
1134
1135 impl IntoValue for chrono::NaiveDate {
1136 fn into_value(self) -> Value {
1137 let year = self.year();
1138 let month = self.month() as u8;
1139 let day = self.day() as u8;
1140 Value::Record(vec![Value::S32(year), Value::U8(month), Value::U8(day)])
1141 }
1142
1143 fn get_type() -> AnalysedType {
1144 analysed_type::record(vec![
1145 analysed_type::field("year", analysed_type::s32()),
1146 analysed_type::field("month", analysed_type::u8()),
1147 analysed_type::field("day", analysed_type::u8()),
1148 ])
1149 }
1150 }
1151
1152 impl IntoValue for chrono::NaiveTime {
1153 fn into_value(self) -> Value {
1154 let hour = self.hour() as u8;
1155 let minute = self.minute() as u8;
1156 let second = self.second() as u8;
1157 let nanosecond = self.nanosecond();
1158
1159 Value::Record(vec![
1160 Value::U8(hour),
1161 Value::U8(minute),
1162 Value::U8(second),
1163 Value::U32(nanosecond),
1164 ])
1165 }
1166
1167 fn get_type() -> AnalysedType {
1168 analysed_type::record(vec![
1169 analysed_type::field("hours", analysed_type::u8()),
1170 analysed_type::field("minutes", analysed_type::u8()),
1171 analysed_type::field("seconds", analysed_type::u8()),
1172 analysed_type::field("nanoseconds", analysed_type::u32()),
1173 ])
1174 }
1175 }
1176
1177 impl IntoValue for chrono::NaiveDateTime {
1178 fn into_value(self) -> Value {
1179 let date = self.date().into_value_and_type();
1180 let time = self.time().into_value_and_type();
1181 Value::Record(vec![date.value, time.value])
1182 }
1183
1184 fn get_type() -> AnalysedType {
1185 analysed_type::record(vec![
1186 analysed_type::field("date", chrono::NaiveDate::get_type()),
1187 analysed_type::field("time", chrono::NaiveTime::get_type()),
1188 ])
1189 }
1190 }
1191
1192 impl IntoValue for chrono::DateTime<chrono::Utc> {
1193 fn into_value(self) -> Value {
1194 let timestamp = self.naive_utc().into_value_and_type();
1195 let offset = self.offset().fix().local_minus_utc();
1196 Value::Record(vec![timestamp.value, Value::S32(offset)])
1197 }
1198
1199 fn get_type() -> AnalysedType {
1200 analysed_type::record(vec![
1201 analysed_type::field("timestamp", chrono::NaiveDateTime::get_type()),
1202 analysed_type::field("offset", analysed_type::s32()),
1203 ])
1204 }
1205 }
1206
1207 impl IntoValue for BitVec {
1208 fn into_value(self) -> Value {
1209 self.into_iter().collect::<Vec<_>>().into_value()
1210 }
1211
1212 fn get_type() -> AnalysedType {
1213 list(bool())
1214 }
1215 }
1216
1217 impl IntoValue for Url {
1218 fn into_value(self) -> Value {
1219 Value::String(self.to_string())
1220 }
1221
1222 fn get_type() -> AnalysedType {
1223 str()
1224 }
1225 }
1226}
1227
1228#[cfg(test)]
1229mod tests {
1230 use crate::analysis::AnalysedType;
1231 use crate::{IntoValue, RpcError, WitType, WitValue};
1232 use test_r::test;
1233
1234 #[test]
1235 fn encoding_rpc_error_type() {
1236 let typ1 = RpcError::get_type();
1237 let encoded: WitType = typ1.clone().into();
1238 let typ2: AnalysedType = encoded.into();
1239 assert_eq!(typ1, typ2);
1240 }
1241
1242 #[test]
1243 fn encoding_wit_value_type() {
1244 let typ1 = WitValue::get_type();
1245 let encoded: WitType = typ1.clone().into();
1246 let typ2: AnalysedType = encoded.into();
1247 assert_eq!(typ1, typ2);
1248 }
1249}