1#[cfg(feature = "fdomain")]
6use fdomain_client::{AsHandleRef as _, HandleOp};
7#[cfg(feature = "fdomain")]
8use fidl::encoding::HandleFor as _;
9use fidl::encoding::{AtRestFlags, DynamicFlags, MAGIC_NUMBER_INITIAL};
10#[cfg(not(feature = "fdomain"))]
11use fidl::{AsHandleRef as _, HandleOp};
12
13#[cfg(feature = "fdomain")]
14use HandleOp as HandleDisposition;
15#[cfg(not(feature = "fdomain"))]
16use fidl::HandleDisposition;
17
18use fidl_constants::{ALLOC_ABSENT_U32, ALLOC_ABSENT_U64, ALLOC_PRESENT_U32, ALLOC_PRESENT_U64};
19
20use std::collections::HashMap;
21
22use crate::error::{Error, Result};
23use crate::library;
24use crate::util::*;
25use crate::value::Value;
26
27type DeferCallback<'n, 't> = dyn FnOnce(&mut EncodeBuffer<'n>, RecursionCounter) -> Result<()> + 't;
29
30fn combine_calls<'n: 't, 't>(calls: Vec<Box<DeferCallback<'n, 't>>>) -> Box<DeferCallback<'n, 't>> {
32 Box::new(move |this, counter| {
33 for call in calls {
34 call(this, counter)?;
35 }
36
37 Ok(())
38 })
39}
40
41enum HandleType<'s> {
42 ClientEnd(&'s str),
43 ServerEnd(&'s str),
44 Bare,
45}
46
47struct EncodeBuffer<'n> {
49 ns: &'n library::Namespace,
50 bytes: Vec<u8>,
51 handles: Vec<HandleDisposition<'static>>,
52}
53
54impl<'n> EncodeBuffer<'n> {
55 fn align_8(&mut self) {
57 self.bytes
58 .extend(std::iter::repeat(0u8).take(alignment_padding_for_size(self.bytes.len())));
59 }
60
61 fn encode_transaction<'n_i: 't, 't>(
62 ns: &'n_i library::Namespace,
63 txid: u32,
64 protocol_name: &str,
65 direction: Direction,
66 method_name: &str,
67 value: Value,
68 ) -> Result<(Vec<u8>, Vec<HandleDisposition<'static>>)> {
69 let mut buf = EncodeBuffer { ns, bytes: Vec::new(), handles: Vec::new() };
70
71 let protocol = match ns.lookup(protocol_name)? {
72 library::LookupResult::Protocol(i) => Ok(i),
73 _ => Err(Error::LibraryError(format!("Could not find protocol '{}'.", protocol_name))),
74 }?;
75
76 let method = protocol.methods.get(method_name).ok_or_else(|| {
77 Error::LibraryError(format!(
78 "Could not find method '{}' on protocol '{}'",
79 method_name, protocol_name
80 ))
81 })?;
82
83 let (ty, has) = match direction {
84 Direction::Request => {
85 if !method.has_response && txid != 0 {
86 return Err(Error::EncodeError(
87 "Non-zero transaction ID for one-way method.".to_owned(),
88 ));
89 }
90 (method.request.as_ref(), method.has_request)
91 }
92 Direction::Response => (method.response.as_ref(), method.has_response),
93 };
94
95 let dynamic_flags =
96 if method.strict { DynamicFlags::empty() } else { DynamicFlags::FLEXIBLE };
97
98 if !has {
99 return Err(Error::LibraryError(format!(
100 "Method '{}' on protocol '{}' has no {}",
101 method_name,
102 protocol_name,
103 direction.to_string()
104 )));
105 }
106
107 buf.bytes.extend(&txid.to_le_bytes());
108 buf.bytes.extend(&AtRestFlags::USE_V2_WIRE_FORMAT.bits().to_le_bytes());
109 buf.bytes.push(dynamic_flags.bits());
110 buf.bytes.push(MAGIC_NUMBER_INITIAL);
111 buf.bytes.extend(&method.ordinal.to_le_bytes());
112
113 if let Some(ty) = ty {
114 buf.encode_type(ty, value)?(&mut buf, RecursionCounter::new())?
115 } else if !matches!(value, Value::Null) {
116 return Err(Error::EncodeError("Value must be null.".to_owned()));
117 } else {
118 };
119 buf.align_8();
120 Ok((buf.bytes, buf.handles))
121 }
122
123 fn encode_struct_nonnull<'t>(
124 &mut self,
125 st: &'n library::Struct,
126 value: Value,
127 start_offset: usize,
128 ) -> Result<Box<DeferCallback<'n, 't>>>
129 where
130 'n: 't,
131 {
132 let start_offset = self.bytes.len() - start_offset;
133
134 let values = match value {
135 Value::Object(s) => Ok(s),
136 _ => Err(Error::EncodeError("Value is not a struct.".to_owned())),
137 }?;
138
139 let mut values = {
140 let mut map = HashMap::with_capacity(values.len());
141
142 for (k, v) in values {
143 map.insert(k, v);
144 }
145
146 map
147 };
148
149 let mut calls = Vec::new();
150
151 for member in &st.members {
152 let value = values.remove(&member.name).unwrap_or(Value::Null);
153 self.bytes.extend(
154 std::iter::repeat(0u8).take(member.offset - (self.bytes.len() - start_offset)),
155 );
156 calls.push(self.encode_type(&member.ty, value)?);
157 }
158
159 if let Some((name, _)) = values.into_iter().next() {
160 Err(Error::EncodeError(format!("Unknown struct member: {}", name)))
161 } else {
162 self.bytes
163 .extend(std::iter::repeat(0u8).take(st.size - (self.bytes.len() - start_offset)));
164 Ok(combine_calls(calls))
165 }
166 }
167
168 fn encode_type<'t>(
169 &mut self,
170 ty: &'n library::Type,
171 value: Value,
172 ) -> Result<Box<DeferCallback<'n, 't>>>
173 where
174 'n: 't,
175 {
176 use library::Type::*;
177
178 match ty {
179 Unknown(_) | UnknownString(_) => {
180 return Err(Error::LibraryError("Unknown type".to_owned()));
181 }
182 Bool => self.encode_raw(if bool::try_from(value)? { &[1u8] } else { &[0u8] }),
183 U8 => self.encode_raw(&u8::try_from(value)?.to_le_bytes()),
184 U16 => self.encode_raw(&u16::try_from(value)?.to_le_bytes()),
185 U32 => self.encode_raw(&u32::try_from(value)?.to_le_bytes()),
186 U64 => self.encode_raw(&u64::try_from(value)?.to_le_bytes()),
187 I8 => self.encode_raw(&i8::try_from(value)?.to_le_bytes()),
188 I16 => self.encode_raw(&i16::try_from(value)?.to_le_bytes()),
189 I32 => self.encode_raw(&i32::try_from(value)?.to_le_bytes()),
190 I64 => self.encode_raw(&i64::try_from(value)?.to_le_bytes()),
191 F32 => self.encode_raw(&f32::try_from(value)?.to_le_bytes()),
192 F64 => self.encode_raw(&f64::try_from(value)?.to_le_bytes()),
193 Array(ty, size) => self.encode_array(ty, *size, value),
194 Vector { ty, nullable, element_count } => {
195 self.encode_vector(ty, *nullable, value, *element_count)
196 }
197 String { nullable, byte_count } => self.encode_string(*nullable, value, *byte_count),
198 Handle { object_type, rights, nullable } => {
199 self.encode_handle(*object_type, *rights, HandleType::Bare, *nullable, value)
200 }
201 FrameworkError => self.encode_raw(&[0, 0, 0, 0]),
202 Endpoint { role, protocol, rights, nullable } => self.encode_handle(
203 fidl::ObjectType::CHANNEL,
204 Some(rights.unwrap_or(fidl::Rights::CHANNEL_DEFAULT)),
205 match role {
206 library::EndpointRole::Client => HandleType::ClientEnd(protocol),
207 library::EndpointRole::Server => HandleType::ServerEnd(protocol),
208 },
209 *nullable,
210 value,
211 ),
212 Identifier { name, nullable } => self.encode_identifier(name.clone(), *nullable, value),
213 }
214 }
215
216 fn encode_raw<'t>(&mut self, data: &[u8]) -> Result<Box<DeferCallback<'n, 't>>>
217 where
218 'n: 't,
219 {
220 self.bytes.extend(data);
221 Ok(Box::new(|_, _| Ok(())))
222 }
223
224 fn encode_array<'t>(
225 &mut self,
226 ty: &'n library::Type,
227 size: usize,
228 value: Value,
229 ) -> Result<Box<DeferCallback<'n, 't>>>
230 where
231 'n: 't,
232 {
233 let values = if let Value::List(v) = value {
234 Ok(v)
235 } else {
236 Err(Error::EncodeError("Expected a list".to_owned()))
237 }?;
238
239 if values.len() != size {
240 return Err(Error::EncodeError(format!("Expected list of length {}", size)));
241 }
242
243 let mut calls = Vec::with_capacity(size);
244
245 for value in values {
246 calls.push(self.encode_type(ty, value)?);
247 }
248
249 Ok(combine_calls(calls))
250 }
251
252 fn encode_vector<'t>(
253 &mut self,
254 ty: &'n library::Type,
255 nullable: bool,
256 value: Value,
257 element_count: Option<usize>,
258 ) -> Result<Box<DeferCallback<'n, 't>>>
259 where
260 'n: 't,
261 {
262 let values = match (value, nullable) {
263 (Value::Null, true) => Ok(None),
264 (Value::Null, false) => {
265 Err(Error::EncodeError("Got null for non-nullable list".to_owned()))
266 }
267 (Value::List(v), _) => Ok(Some(v)),
268 _ => Err(Error::EncodeError("Expected a list".to_owned())),
269 }?;
270
271 if let Some(values) = values {
272 if element_count.map(|x| x < values.len()).unwrap_or(false) {
273 return Err(Error::EncodeError("Vector exceeded max size".to_owned()));
274 }
275
276 self.bytes.extend(&(values.len() as u64).to_le_bytes());
277 self.bytes.extend(&ALLOC_PRESENT_U64.to_le_bytes());
278 Ok(Box::new(move |this, counter| {
279 let counter = counter.next()?;
280 let mut calls = Vec::with_capacity(values.len());
281
282 for value in values {
283 calls.push(this.encode_type(ty, value)?);
284 }
285
286 this.align_8();
287
288 for call in calls {
289 call(this, counter)?;
290 }
291
292 Ok(())
293 }))
294 } else {
295 self.bytes.extend(std::iter::repeat(0u8).take(16));
296 Ok(Box::new(|_, _| Ok(())))
297 }
298 }
299
300 fn encode_string<'t>(
301 &mut self,
302 nullable: bool,
303 value: Value,
304 byte_count: Option<usize>,
305 ) -> Result<Box<DeferCallback<'n, 't>>>
306 where
307 'n: 't,
308 {
309 let string = match (value, nullable) {
310 (Value::Null, true) => Ok(None),
311 (Value::Null, false) => {
312 Err(Error::EncodeError("Got null for non-nullable string".to_owned()))
313 }
314 (Value::String(s), _) => Ok(Some(s)),
315 _ => Err(Error::EncodeError("Expected a string".to_owned())),
316 }?;
317
318 if let Some(string) = string {
319 if byte_count.map(|x| x < string.len()).unwrap_or(false) {
320 return Err(Error::EncodeError("String exceeded max size".to_owned()));
321 }
322
323 self.bytes.extend(&(string.len() as u64).to_le_bytes());
324 self.bytes.extend(&ALLOC_PRESENT_U64.to_le_bytes());
325 Ok(Box::new(move |this, counter| {
326 let _counter = counter.next()?;
327 this.bytes.extend(string.as_bytes());
328 this.align_8();
329 Ok(())
330 }))
331 } else {
332 self.bytes.extend(std::iter::repeat(0u8).take(16));
333 Ok(Box::new(|_, _| Ok(())))
334 }
335 }
336
337 fn encode_handle<'t>(
338 &mut self,
339 object_type: fidl::ObjectType,
340 rights: Option<fidl::Rights>,
341 expect: HandleType<'_>,
342 nullable: bool,
343 value: Value,
344 ) -> Result<Box<DeferCallback<'n, 't>>>
345 where
346 'n: 't,
347 {
348 let (handle, handle_rights) = match (value, nullable, expect) {
349 (Value::Null, true, _) => Ok((None, None)),
350 (Value::Handle(h, _, _), true, _) if h.is_invalid() => Ok((None, None)),
351 (Value::ServerEnd(h, _, _), true, _) if h.as_handle_ref().is_invalid() => {
352 Ok((None, None))
353 }
354 (Value::ClientEnd(h, _, _), true, _) if h.as_handle_ref().is_invalid() => {
355 Ok((None, None))
356 }
357 (Value::Handle(h, _, _), false, _) if h.is_invalid() => {
358 Err(Error::EncodeError("Got invalid handle for non-nullable handle".to_owned()))
359 }
360 (Value::ServerEnd(h, _, _), false, _) if h.as_handle_ref().is_invalid() => {
361 Err(Error::EncodeError("Got invalid handle for non-nullable handle".to_owned()))
362 }
363 (Value::ClientEnd(h, _, _), false, _) if h.as_handle_ref().is_invalid() => {
364 Err(Error::EncodeError("Got invalid handle for non-nullable handle".to_owned()))
365 }
366 (Value::Null, false, _) => {
367 Err(Error::EncodeError("Got null for non-nullable handle".to_owned()))
368 }
369 (Value::Handle(h, s, r), _, _) => {
370 if s != object_type && s != fidl::ObjectType::NONE {
371 Err(Error::EncodeError(format!(
372 "Expected object type {object_type:?} got {s:?}"
373 )))
374 } else {
375 Ok((Some(h), r))
376 }
377 }
378 (Value::ServerEnd(h, s, r), _, HandleType::ServerEnd(expect))
379 | (Value::ClientEnd(h, s, r), _, HandleType::ClientEnd(expect)) => {
380 if expect != s {
381 Err(Error::EncodeError(format!(
382 "Expected endpoint for protocol {expect}, got one for {s}"
383 )))
384 } else if object_type != fidl::ObjectType::CHANNEL {
385 Err(Error::EncodeError(format!(
386 "Expected object type {object_type:?} got channel for protocol {s}"
387 )))
388 } else {
389 Ok((Some(h.into()), r))
390 }
391 }
392 (Value::ServerEnd(_, s, _), _, HandleType::ClientEnd(expect))
393 | (Value::ClientEnd(_, s, _), _, HandleType::ServerEnd(expect)) => {
394 if expect != s {
395 Err(Error::EncodeError(format!(
396 "Expected endpoint for protocol {expect}, got one for {s}"
397 )))
398 } else if object_type != fidl::ObjectType::CHANNEL {
399 Err(Error::EncodeError(format!(
400 "Expected object type {object_type:?} got channel for protocol {s}"
401 )))
402 } else {
403 Err(Error::EncodeError(format!("Got wrong end of channel for {expect}")))
404 }
405 }
406 (Value::ServerEnd(h, s, r), _, HandleType::Bare)
407 | (Value::ClientEnd(h, s, r), _, HandleType::Bare) => {
408 if object_type != fidl::ObjectType::CHANNEL {
409 Err(Error::EncodeError(format!(
410 "Expected object type {object_type:?} got channel for protocol {s}"
411 )))
412 } else {
413 Ok((Some(h.into()), r))
414 }
415 }
416 _ => Err(Error::EncodeError("Expected a handle".to_owned())),
417 }?;
418
419 let encoded_rights = match (handle_rights, rights) {
420 (Some(_), Some(rights)) => rights,
421 (Some(handle_rights), None) => handle_rights,
422 (None, Some(rights)) => rights,
423 (None, None) => fidl::Rights::SAME_RIGHTS,
424 };
425
426 if let Some(handle) = handle {
427 #[cfg(feature = "fdomain")]
428 let handle_op = HandleOp::Move(handle, encoded_rights);
429 #[cfg(not(feature = "fdomain"))]
430 let handle_op = HandleOp::Move(handle);
431 self.bytes.extend(&ALLOC_PRESENT_U32.to_le_bytes());
432 Ok(Box::new(move |this, _| {
433 #[cfg(feature = "fdomain")]
434 {
435 let _ = object_type;
436 this.handles.push(handle_op);
437 }
438 #[cfg(not(feature = "fdomain"))]
439 this.handles.push(HandleDisposition::new(
440 handle_op,
441 object_type,
442 encoded_rights,
443 fidl::Status::OK,
444 ));
445 Ok(())
446 }))
447 } else {
448 self.bytes.extend(&ALLOC_ABSENT_U32.to_le_bytes());
449 Ok(Box::new(|_, _| Ok(())))
450 }
451 }
452
453 fn encode_identifier<'t>(
454 &mut self,
455 name: String,
456 nullable: bool,
457 value: Value,
458 ) -> Result<Box<DeferCallback<'n, 't>>>
459 where
460 'n: 't,
461 {
462 use library::LookupResult::*;
463 match (self.ns.lookup(&name)?, nullable) {
464 (Bits(b), false) => self.encode_bits(b, value),
465 (Enum(e), false) => self.encode_enum(e, value),
466 (Table(t), false) => self.encode_table(t, value),
467 (Struct(s), nullable) => self.encode_struct(s, nullable, value),
468 (Union(u), nullable) => self.encode_union(u, nullable, value),
469 (Protocol(_), _) => Err(Error::LibraryError(format!(
470 "Protocol names cannot be used as identifiers: {}",
471 name
472 ))),
473 _ => Err(Error::LibraryError(format!("Type {} shouldn't be nullable", name))),
474 }
475 }
476
477 fn encode_bits<'t>(
478 &mut self,
479 bits: &'n library::Bits,
480 value: Value,
481 ) -> Result<Box<DeferCallback<'n, 't>>>
482 where
483 'n: 't,
484 {
485 let value = match value {
486 Value::Bits(name, inner) => {
487 if name == bits.name {
488 *inner
489 } else {
490 return Err(Error::EncodeError(format!(
491 "Expected {}, got {}",
492 bits.name, name
493 )));
494 }
495 }
496 _ => value,
497 };
498
499 let data = u64::try_from(&value).unwrap_or(0);
502
503 if bits.strict && data & !bits.mask != 0 {
504 Err(Error::EncodeError(format!("Invalid bits set on {}", bits.name)))
505 } else {
506 self.encode_type(&bits.ty, value)
507 }
508 }
509
510 fn encode_enum<'t>(
511 &mut self,
512 en: &'n library::Enum,
513 value: Value,
514 ) -> Result<Box<DeferCallback<'n, 't>>>
515 where
516 'n: 't,
517 {
518 let value = match value {
519 Value::Enum(name, inner) => {
520 if name == en.name {
521 *inner
522 } else {
523 return Err(Error::EncodeError(format!("Expected {}, got {}", en.name, name)));
524 }
525 }
526 _ => value,
527 };
528
529 for item in &en.members {
530 if !en.strict || item.value.cast_equals(&value) {
531 return self.encode_type(&en.ty, value);
532 }
533 }
534
535 Err(Error::EncodeError("Invalid enum variant".to_owned()))
536 }
537
538 fn encode_struct<'t>(
539 &mut self,
540 st: &'n library::Struct,
541 nullable: bool,
542 value: Value,
543 ) -> Result<Box<DeferCallback<'n, 't>>>
544 where
545 'n: 't,
546 {
547 let value = match (value, nullable) {
548 (Value::Null, true) => Ok(None),
549 (Value::Null, false) => Err(Error::EncodeError("Struct can't be null".to_owned())),
550 (value, _) => Ok(Some(value)),
551 }?;
552
553 if let Some(value) = value {
554 if nullable {
555 self.bytes.extend(&ALLOC_PRESENT_U64.to_le_bytes());
556 Ok(Box::new(move |this, counter| {
557 let counter = counter.next()?;
558 let call = this.encode_struct_nonnull(st, value, 0)?;
559 this.align_8();
560 call(this, counter)
561 }))
562 } else {
563 self.encode_struct_nonnull(st, value, 0)
564 }
565 } else {
566 self.bytes.extend(&ALLOC_ABSENT_U64.to_le_bytes());
567 Ok(Box::new(|_, _| Ok(())))
568 }
569 }
570
571 fn encode_envelope<'t>(
572 &mut self,
573 ty: &'n library::Type,
574 value: Value,
575 ) -> Result<Box<DeferCallback<'n, 't>>>
576 where
577 'n: 't,
578 {
579 let header_pos = self.bytes.len();
580 self.bytes.extend(&[0u8; 8]);
581
582 if let Value::Null = value {
583 Ok(Box::new(|_, _| Ok(())))
584 } else {
585 Ok(Box::new(move |this, counter| {
586 let counter = counter.next()?;
587 let start = this.bytes.len();
588 let handle_start = this.handles.len();
589
590 let header = if ty.inline_size(this.ns)? > 4 {
591 let call = this.encode_type(ty, value)?;
592
593 this.align_8();
594 call(this, counter)?;
595 let size = (this.bytes.len() - start) as u32;
596 let handle_count = (this.handles.len() - handle_start) as u16;
597
598 debug_assert!(size > 0 || handle_count > 0);
599 let mut header = Vec::new();
600 header.extend(&size.to_le_bytes());
601 header.extend(&handle_count.to_le_bytes());
602 header.extend(&0u16.to_le_bytes());
603 header
604 } else {
605 let mut header_buf =
606 EncodeBuffer { ns: this.ns, bytes: Vec::new(), handles: Vec::new() };
607 header_buf.encode_type(ty, value)?(&mut header_buf, counter)?;
608 let EncodeBuffer { bytes: mut header, handles, .. } = header_buf;
609 header.resize(4, 0);
610 header.extend(&(handles.len() as u16).to_le_bytes());
611 header.extend(&1u16.to_le_bytes());
612 this.handles.extend(handles);
613 header
614 };
615
616 this.bytes.splice(header_pos..(header_pos + header.len()), header.into_iter());
617 Ok(())
618 }))
619 }
620 }
621
622 fn encode_union<'t>(
623 &mut self,
624 union: &'n library::TableOrUnion,
625 nullable: bool,
626 value: Value,
627 ) -> Result<Box<DeferCallback<'n, 't>>>
628 where
629 'n: 't,
630 {
631 let entry = match value {
632 Value::Null => Ok(None),
633 Value::Union(u, n, b) if *u == union.name => Ok(Some((n, *b))),
634 _ => Err(Error::EncodeError(format!("Expected {}", union.name))),
635 }?;
636
637 if let Some((variant, value)) = entry {
638 for member in union.members.values() {
639 if *member.name == *variant {
640 self.bytes.extend(&member.ordinal.to_le_bytes());
641 return self.encode_envelope(&member.ty, value);
642 }
643 }
644
645 Err(Error::EncodeError(format!("Unrecognized union variant: '{}'", variant)))
646 } else if nullable {
647 self.bytes.extend(std::iter::repeat(0u8).take(16));
648 Ok(Box::new(|_, _| Ok(())))
649 } else {
650 Err(Error::EncodeError("Got null for non-nullable Union".to_owned()))
651 }
652 }
653
654 fn encode_table<'t>(
655 &mut self,
656 table: &'n library::TableOrUnion,
657 value: Value,
658 ) -> Result<Box<DeferCallback<'n, 't>>>
659 where
660 'n: 't,
661 {
662 let values = match value {
663 Value::Object(values) => Ok(values),
664 _ => Err(Error::EncodeError(format!("Could not convert to {}", table.name))),
665 }?;
666
667 let mut values_array = Vec::new();
668 for (value_name, value) in values {
669 for (&ord, member) in &table.members {
670 let array_idx = usize::try_from(ord - 1).unwrap();
671 if values_array.len() <= array_idx {
672 values_array.resize_with(array_idx + 1, || None);
673 }
674 if *member.name == value_name {
675 values_array[array_idx] = Some((&member.ty, value));
676 break;
677 }
678 }
679 }
680
681 while values_array.last().map(|x| x.is_none()).unwrap_or(false) {
682 values_array.pop();
683 }
684
685 self.bytes.extend(&(values_array.len() as u64).to_le_bytes());
686 self.bytes.extend(&ALLOC_PRESENT_U64.to_le_bytes());
687
688 Ok(Box::new(move |this, counter| {
689 let counter = counter.next()?;
690 let mut calls = Vec::with_capacity(values_array.len());
691
692 for slot in values_array.into_iter() {
693 if let Some((ty, item)) = slot {
694 calls.push(this.encode_envelope(ty, item)?);
695 } else {
696 this.bytes.extend(&ALLOC_ABSENT_U64.to_le_bytes());
697 }
698 }
699
700 for call in calls {
701 call(this, counter)?;
702 }
703
704 Ok(())
705 }))
706 }
707}
708
709pub fn encode_request(
711 ns: &library::Namespace,
712 txid: u32,
713 protocol_name: &str,
714 method_name: &str,
715 value: Value,
716) -> Result<(Vec<u8>, Vec<HandleDisposition<'static>>)> {
717 EncodeBuffer::encode_transaction(
718 ns,
719 txid,
720 protocol_name,
721 Direction::Request,
722 method_name,
723 value,
724 )
725}
726
727pub fn encode_response(
729 ns: &library::Namespace,
730 txid: u32,
731 protocol_name: &str,
732 method_name: &str,
733 value: Value,
734) -> Result<(Vec<u8>, Vec<HandleDisposition<'static>>)> {
735 EncodeBuffer::encode_transaction(
736 ns,
737 txid,
738 protocol_name,
739 Direction::Response,
740 method_name,
741 value,
742 )
743}
744
745pub fn encode(
747 ns: &library::Namespace,
748 type_name: &str,
749 nullable: bool,
750 value: Value,
751) -> Result<(Vec<u8>, Vec<HandleDisposition<'static>>)> {
752 let mut buf = EncodeBuffer { ns, bytes: Vec::new(), handles: Vec::new() };
753 let cb = buf.encode_identifier(type_name.to_owned(), nullable, value)?;
754 buf.align_8();
755 cb(&mut buf, RecursionCounter::new()).map(|_| (buf.bytes, buf.handles))
756}