1use std::borrow::Cow;
2use std::cell::RefCell;
3use std::collections::HashSet;
4use std::ops::{Deref, DerefMut};
5use std::sync::Arc;
6
7use crate::error::{Error, ErrorKind};
8use crate::utils::UndefinedBehavior;
9use crate::value::{
10 DynObject, ObjectRepr, Packed, SmallStr, StringType, Value, ValueKind, ValueMap, ValueRepr,
11};
12use crate::vm::State;
13
14use super::{Enumerator, Object};
15
16pub trait FunctionResult {
25 #[doc(hidden)]
26 fn into_result(self) -> Result<Value, Error>;
27}
28
29impl<I: Into<Value>> FunctionResult for Result<I, Error> {
30 fn into_result(self) -> Result<Value, Error> {
31 self.map(Into::into)
32 }
33}
34
35impl<I: Into<Value>> FunctionResult for I {
36 fn into_result(self) -> Result<Value, Error> {
37 Ok(self.into())
38 }
39}
40
41pub trait FunctionArgs<'a> {
52 type Output;
54
55 #[doc(hidden)]
57 fn from_values(state: Option<&'a State>, values: &'a [Value]) -> Result<Self::Output, Error>;
58}
59
60#[inline(always)]
92pub fn from_args<'a, Args>(values: &'a [Value]) -> Result<Args, Error>
93where
94 Args: FunctionArgs<'a, Output = Args>,
95{
96 Args::from_values(None, values)
97}
98
99pub trait ArgType<'a> {
145 type Output;
147
148 #[doc(hidden)]
149 fn from_value(value: Option<&'a Value>) -> Result<Self::Output, Error>;
150
151 #[doc(hidden)]
152 fn from_value_owned(_value: Value) -> Result<Self::Output, Error> {
153 Err(Error::new(
154 ErrorKind::InvalidOperation,
155 "type conversion is not legal in this situation (implicit borrow)",
156 ))
157 }
158
159 #[doc(hidden)]
160 fn from_state_and_value(
161 state: Option<&'a State>,
162 value: Option<&'a Value>,
163 ) -> Result<(Self::Output, usize), Error> {
164 if value.map_or(false, |x| x.is_undefined())
165 && state.map_or(false, |x| {
166 matches!(x.undefined_behavior(), UndefinedBehavior::Strict)
167 })
168 {
169 Err(Error::from(ErrorKind::UndefinedError))
170 } else {
171 Ok((ok!(Self::from_value(value)), 1))
172 }
173 }
174
175 #[doc(hidden)]
176 #[inline(always)]
177 fn from_state_and_values(
178 state: Option<&'a State>,
179 values: &'a [Value],
180 offset: usize,
181 ) -> Result<(Self::Output, usize), Error> {
182 Self::from_state_and_value(state, values.get(offset))
183 }
184
185 #[doc(hidden)]
186 #[inline(always)]
187 fn is_trailing() -> bool {
188 false
189 }
190}
191
192macro_rules! tuple_impls {
193 ( $( $name:ident )* * $rest_name:ident ) => {
194 impl<'a, $($name,)* $rest_name> FunctionArgs<'a> for ($($name,)* $rest_name,)
195 where $($name: ArgType<'a>,)* $rest_name: ArgType<'a>
196 {
197 type Output = ($($name::Output,)* $rest_name::Output ,);
198
199 fn from_values(state: Option<&'a State>, mut values: &'a [Value]) -> Result<Self::Output, Error> {
200 #![allow(non_snake_case, unused)]
201 $( let $name; )*
202 let mut $rest_name = None;
203 let mut idx = 0;
204
205 let rest_first = $rest_name::is_trailing() && !values.is_empty();
210 if rest_first {
211 let (val, offset) = ok!($rest_name::from_state_and_values(state, values, values.len() - 1));
212 $rest_name = Some(val);
213 values = &values[..values.len() - offset];
214 }
215 $(
216 let (val, offset) = ok!($name::from_state_and_values(state, values, idx));
217 $name = val;
218 idx += offset;
219 )*
220
221 if !rest_first {
222 let (val, offset) = ok!($rest_name::from_state_and_values(state, values, idx));
223 $rest_name = Some(val);
224 idx += offset;
225 }
226
227 if values.get(idx).is_some() {
228 Err(Error::from(ErrorKind::TooManyArguments))
229 } else {
230 Ok(($($name,)* unsafe { $rest_name.unwrap_unchecked() },))
233 }
234 }
235 }
236 };
237}
238
239impl<'a> FunctionArgs<'a> for () {
240 type Output = ();
241
242 fn from_values(_state: Option<&'a State>, values: &'a [Value]) -> Result<Self::Output, Error> {
243 if values.is_empty() {
244 Ok(())
245 } else {
246 Err(Error::from(ErrorKind::TooManyArguments))
247 }
248 }
249}
250
251tuple_impls! { *A }
252tuple_impls! { A *B }
253tuple_impls! { A B *C }
254tuple_impls! { A B C *D }
255tuple_impls! { A B C D *E }
256
257impl From<ValueRepr> for Value {
258 #[inline(always)]
259 fn from(val: ValueRepr) -> Value {
260 Value(val)
261 }
262}
263
264impl<'a> From<&'a [u8]> for Value {
265 #[inline(always)]
266 fn from(val: &'a [u8]) -> Self {
267 ValueRepr::Bytes(Arc::new(val.into())).into()
268 }
269}
270
271impl<'a> From<&'a str> for Value {
272 #[inline(always)]
273 fn from(val: &'a str) -> Self {
274 SmallStr::try_new(val)
275 .map(|small_str| Value(ValueRepr::SmallStr(small_str)))
276 .unwrap_or_else(|| Value::from(val.to_string()))
277 }
278}
279
280impl<'a> From<&'a String> for Value {
281 #[inline(always)]
282 fn from(val: &'a String) -> Self {
283 Value::from(val.as_str())
284 }
285}
286
287impl From<String> for Value {
288 #[inline(always)]
289 fn from(val: String) -> Self {
290 ValueRepr::String(Arc::from(val), StringType::Normal).into()
291 }
292}
293
294impl<'a> From<Cow<'a, str>> for Value {
295 #[inline(always)]
296 fn from(val: Cow<'a, str>) -> Self {
297 match val {
298 Cow::Borrowed(x) => x.into(),
299 Cow::Owned(x) => x.into(),
300 }
301 }
302}
303
304impl From<Arc<str>> for Value {
305 fn from(value: Arc<str>) -> Self {
306 Value(ValueRepr::String(value, StringType::Normal))
307 }
308}
309
310impl From<()> for Value {
311 #[inline(always)]
312 fn from(_: ()) -> Self {
313 ValueRepr::None.into()
314 }
315}
316
317impl<V: Into<Value>> FromIterator<V> for Value {
318 fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
319 Value::from_object(iter.into_iter().map(Into::into).collect::<Vec<Value>>())
320 }
321}
322
323impl<K: Into<Value>, V: Into<Value>> FromIterator<(K, V)> for Value {
324 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
325 Value::from_object(
326 iter.into_iter()
327 .map(|(k, v)| (k.into(), v.into()))
328 .collect::<ValueMap>(),
329 )
330 }
331}
332
333macro_rules! value_from {
334 ($src:ty, $dst:ident) => {
335 impl From<$src> for Value {
336 #[inline(always)]
337 fn from(val: $src) -> Self {
338 ValueRepr::$dst(val as _).into()
339 }
340 }
341 };
342}
343
344impl From<i128> for Value {
345 #[inline(always)]
346 fn from(val: i128) -> Self {
347 ValueRepr::I128(Packed(val)).into()
348 }
349}
350
351impl From<u128> for Value {
352 #[inline(always)]
353 fn from(val: u128) -> Self {
354 ValueRepr::U128(Packed(val)).into()
355 }
356}
357
358impl From<char> for Value {
359 #[inline(always)]
360 fn from(val: char) -> Self {
361 let mut buf = [0u8; 4];
362 ValueRepr::SmallStr(SmallStr::try_new(val.encode_utf8(&mut buf)).unwrap()).into()
363 }
364}
365
366value_from!(bool, Bool);
367value_from!(u8, U64);
368value_from!(u16, U64);
369value_from!(u32, U64);
370value_from!(u64, U64);
371value_from!(i8, I64);
372value_from!(i16, I64);
373value_from!(i32, I64);
374value_from!(i64, I64);
375value_from!(f32, F64);
376value_from!(f64, F64);
377value_from!(Arc<Vec<u8>>, Bytes);
378value_from!(DynObject, Object);
379
380fn unsupported_conversion(kind: ValueKind, target: &str) -> Error {
381 Error::new(
382 ErrorKind::InvalidOperation,
383 format!("cannot convert {kind} to {target}"),
384 )
385}
386
387macro_rules! primitive_try_from {
388 ($ty:ident, {
389 $($pat:pat $(if $if_expr:expr)? => $expr:expr,)*
390 }) => {
391 impl TryFrom<Value> for $ty {
392 type Error = Error;
393
394 fn try_from(value: Value) -> Result<Self, Self::Error> {
395 match value.0 {
396 $($pat $(if $if_expr)? => TryFrom::try_from($expr).ok(),)*
397 _ => None
398 }.ok_or_else(|| unsupported_conversion(value.kind(), stringify!($ty)))
399 }
400 }
401
402 impl<'a> ArgType<'a> for $ty {
403 type Output = Self;
404 fn from_value(value: Option<&Value>) -> Result<Self, Error> {
405 match value {
406 Some(value) => TryFrom::try_from(value.clone()),
407 None => Err(Error::from(ErrorKind::MissingArgument))
408 }
409 }
410
411 fn from_value_owned(value: Value) -> Result<Self, Error> {
412 TryFrom::try_from(value)
413 }
414 }
415 }
416}
417
418macro_rules! primitive_int_try_from {
419 ($ty:ident) => {
420 primitive_try_from!($ty, {
421 ValueRepr::Bool(val) => val as usize,
422 ValueRepr::I64(val) => val,
423 ValueRepr::U64(val) => val,
424 ValueRepr::F64(val) if (val as i64 as f64 == val) => val as i64,
426 ValueRepr::I128(val) => val.0,
427 ValueRepr::U128(val) => val.0,
428 });
429 }
430}
431
432primitive_int_try_from!(u8);
433primitive_int_try_from!(u16);
434primitive_int_try_from!(u32);
435primitive_int_try_from!(u64);
436primitive_int_try_from!(u128);
437primitive_int_try_from!(i8);
438primitive_int_try_from!(i16);
439primitive_int_try_from!(i32);
440primitive_int_try_from!(i64);
441primitive_int_try_from!(i128);
442primitive_int_try_from!(usize);
443
444primitive_try_from!(bool, {
445 ValueRepr::Bool(val) => val,
446});
447primitive_try_from!(char, {
448 ValueRepr::String(ref val, _) => {
449 let mut char_iter = val.chars();
450 ok!(char_iter.next().filter(|_| char_iter.next().is_none()).ok_or_else(|| {
451 unsupported_conversion(ValueKind::String, "non single character string")
452 }))
453 },
454 ValueRepr::SmallStr(ref val) => {
455 let mut char_iter = val.as_str().chars();
456 ok!(char_iter.next().filter(|_| char_iter.next().is_none()).ok_or_else(|| {
457 unsupported_conversion(ValueKind::String, "non single character string")
458 }))
459 },
460});
461primitive_try_from!(f32, {
462 ValueRepr::U64(val) => val as f32,
463 ValueRepr::I64(val) => val as f32,
464 ValueRepr::U128(val) => val.0 as f32,
465 ValueRepr::I128(val) => val.0 as f32,
466 ValueRepr::F64(val) => val as f32,
467});
468primitive_try_from!(f64, {
469 ValueRepr::U64(val) => val as f64,
470 ValueRepr::I64(val) => val as f64,
471 ValueRepr::U128(val) => val.0 as f64,
472 ValueRepr::I128(val) => val.0 as f64,
473 ValueRepr::F64(val) => val,
474});
475
476impl<'a> ArgType<'a> for &str {
477 type Output = &'a str;
478
479 fn from_value(value: Option<&'a Value>) -> Result<Self::Output, Error> {
480 match value {
481 Some(value) => value
482 .as_str()
483 .ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "value is not a string")),
484 None => Err(Error::from(ErrorKind::MissingArgument)),
485 }
486 }
487}
488
489impl TryFrom<Value> for Arc<str> {
490 type Error = Error;
491
492 fn try_from(value: Value) -> Result<Self, Self::Error> {
493 match value.0 {
494 ValueRepr::String(x, _) => Ok(x),
495 ValueRepr::SmallStr(x) => Ok(Arc::from(x.as_str())),
496 ValueRepr::Bytes(ref x) => Ok(Arc::from(String::from_utf8_lossy(x))),
497 _ => Err(Error::new(
498 ErrorKind::InvalidOperation,
499 "value is not a string",
500 )),
501 }
502 }
503}
504
505impl<'a> ArgType<'a> for Arc<str> {
506 type Output = Arc<str>;
507
508 fn from_value(value: Option<&'a Value>) -> Result<Self::Output, Error> {
509 match value {
510 Some(value) => TryFrom::try_from(value.clone()),
511 None => Err(Error::from(ErrorKind::MissingArgument)),
512 }
513 }
514}
515
516impl<'a> ArgType<'a> for &[u8] {
517 type Output = &'a [u8];
518
519 fn from_value(value: Option<&'a Value>) -> Result<Self::Output, Error> {
520 match value {
521 Some(value) => value
522 .as_bytes()
523 .ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "value is not in bytes")),
524 None => Err(Error::from(ErrorKind::MissingArgument)),
525 }
526 }
527}
528
529impl<'a, T: ArgType<'a>> ArgType<'a> for Option<T> {
530 type Output = Option<T::Output>;
531
532 fn from_value(value: Option<&'a Value>) -> Result<Self::Output, Error> {
533 match value {
534 Some(value) => {
535 if value.is_undefined() || value.is_none() {
536 Ok(None)
537 } else {
538 T::from_value(Some(value)).map(Some)
539 }
540 }
541 None => Ok(None),
542 }
543 }
544
545 fn from_value_owned(value: Value) -> Result<Self::Output, Error> {
546 if value.is_undefined() || value.is_none() {
547 Ok(None)
548 } else {
549 T::from_value_owned(value).map(Some)
550 }
551 }
552}
553
554impl<'a> ArgType<'a> for Cow<'_, str> {
555 type Output = Cow<'a, str>;
556
557 #[inline(always)]
558 fn from_value(value: Option<&'a Value>) -> Result<Cow<'a, str>, Error> {
559 match value {
560 Some(value) => Ok(match value.0 {
561 ValueRepr::String(ref s, _) => Cow::Borrowed(s as &str),
562 ValueRepr::SmallStr(ref s) => Cow::Borrowed(s.as_str()),
563 _ => {
564 if value.is_kwargs() {
565 return Err(Error::new(
566 ErrorKind::InvalidOperation,
567 "cannot convert kwargs to string",
568 ));
569 }
570 Cow::Owned(value.to_string())
571 }
572 }),
573 None => Err(Error::from(ErrorKind::MissingArgument)),
574 }
575 }
576}
577
578impl<'a> ArgType<'a> for &Value {
579 type Output = &'a Value;
580
581 #[inline(always)]
582 fn from_value(value: Option<&'a Value>) -> Result<&'a Value, Error> {
583 match value {
584 Some(value) => Ok(value),
585 None => Err(Error::from(ErrorKind::MissingArgument)),
586 }
587 }
588}
589
590impl<'a> ArgType<'a> for &[Value] {
591 type Output = &'a [Value];
592
593 #[inline(always)]
594 fn from_value(value: Option<&'a Value>) -> Result<&'a [Value], Error> {
595 match value {
596 Some(value) => Ok(std::slice::from_ref(value)),
597 None => Err(Error::from(ErrorKind::MissingArgument)),
598 }
599 }
600
601 fn from_state_and_values(
602 _state: Option<&'a State>,
603 values: &'a [Value],
604 offset: usize,
605 ) -> Result<(&'a [Value], usize), Error> {
606 let args = values.get(offset..).unwrap_or_default();
607 Ok((args, args.len()))
608 }
609}
610
611impl<'a, T: Object + 'static> ArgType<'a> for &T {
612 type Output = &'a T;
613
614 #[inline(always)]
615 fn from_value(value: Option<&'a Value>) -> Result<Self::Output, Error> {
616 match value {
617 Some(value) => value
618 .downcast_object_ref()
619 .ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "expected object")),
620 None => Err(Error::from(ErrorKind::MissingArgument)),
621 }
622 }
623}
624
625impl<'a, T: Object + 'static> ArgType<'a> for Arc<T> {
626 type Output = Arc<T>;
627
628 #[inline(always)]
629 fn from_value(value: Option<&'a Value>) -> Result<Self::Output, Error> {
630 match value {
631 Some(value) => value
632 .downcast_object()
633 .ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "expected object")),
634 None => Err(Error::from(ErrorKind::MissingArgument)),
635 }
636 }
637}
638
639#[derive(Debug)]
659pub struct Rest<T>(pub Vec<T>);
660
661impl<T> Deref for Rest<T> {
662 type Target = Vec<T>;
663
664 fn deref(&self) -> &Self::Target {
665 &self.0
666 }
667}
668
669impl<T> DerefMut for Rest<T> {
670 fn deref_mut(&mut self) -> &mut Self::Target {
671 &mut self.0
672 }
673}
674
675impl<'a, T: ArgType<'a, Output = T>> ArgType<'a> for Rest<T> {
676 type Output = Self;
677
678 fn from_value(value: Option<&'a Value>) -> Result<Self, Error> {
679 Ok(Rest(ok!(value
680 .iter()
681 .map(|v| T::from_value(Some(v)))
682 .collect::<Result<_, _>>())))
683 }
684
685 fn from_state_and_values(
686 _state: Option<&'a State>,
687 values: &'a [Value],
688 offset: usize,
689 ) -> Result<(Self, usize), Error> {
690 let args = values.get(offset..).unwrap_or_default();
691 Ok((
692 Rest(ok!(args
693 .iter()
694 .map(|v| T::from_value(Some(v)))
695 .collect::<Result<_, _>>())),
696 args.len(),
697 ))
698 }
699}
700
701#[derive(Debug, Clone)]
757pub struct Kwargs {
758 pub(crate) values: Arc<KwargsValues>,
759 used: RefCell<HashSet<String>>,
760}
761
762#[repr(transparent)]
763#[derive(Default, Debug)]
764pub(crate) struct KwargsValues(ValueMap);
765
766impl Deref for KwargsValues {
767 type Target = ValueMap;
768
769 fn deref(&self) -> &Self::Target {
770 &self.0
771 }
772}
773
774impl KwargsValues {
775 fn as_value_map<'a>(self: &'a Arc<Self>) -> &'a Arc<ValueMap> {
776 unsafe { std::mem::transmute(self) }
778 }
779}
780
781impl Object for KwargsValues {
782 fn get_value(self: &Arc<Self>, key: &Value) -> Option<Value> {
783 self.as_value_map().get_value(key)
784 }
785
786 fn enumerate(self: &Arc<Self>) -> Enumerator {
787 self.as_value_map().enumerate()
788 }
789}
790
791impl<'a> ArgType<'a> for Kwargs {
792 type Output = Self;
793
794 fn from_value(value: Option<&'a Value>) -> Result<Self, Error> {
795 match value {
796 Some(value) => {
797 Kwargs::extract(value).ok_or_else(|| Error::from(ErrorKind::MissingArgument))
798 }
799 None => Ok(Kwargs::new(Default::default())),
800 }
801 }
802
803 fn from_state_and_values(
804 _state: Option<&'a State>,
805 values: &'a [Value],
806 offset: usize,
807 ) -> Result<(Self, usize), Error> {
808 let args = values
809 .get(offset)
810 .and_then(Kwargs::extract)
811 .map(|kwargs| (kwargs, 1))
812 .unwrap_or_else(|| (Kwargs::new(Default::default()), 0));
813
814 Ok(args)
815 }
816
817 fn is_trailing() -> bool {
818 true
819 }
820}
821
822impl Kwargs {
823 fn new(map: Arc<KwargsValues>) -> Kwargs {
824 Kwargs {
825 values: map,
826 used: RefCell::new(HashSet::new()),
827 }
828 }
829
830 pub(crate) fn extract(value: &Value) -> Option<Kwargs> {
832 value
833 .as_object()
834 .and_then(|x| x.downcast::<KwargsValues>())
835 .map(Kwargs::new)
836 }
837
838 pub(crate) fn wrap(map: ValueMap) -> Value {
840 Value::from_object(KwargsValues(map))
841 }
842
843 pub fn peek<'a, T>(&'a self, key: &'a str) -> Result<T, Error>
845 where
846 T: ArgType<'a, Output = T>,
847 {
848 T::from_value(self.values.get(&Value::from(key))).map_err(|mut err| {
849 if err.kind() == ErrorKind::MissingArgument && err.detail().is_none() {
850 err.set_detail(format!("missing keyword argument '{}'", key));
851 }
852 err
853 })
854 }
855
856 pub fn get<'a, T>(&'a self, key: &'a str) -> Result<T, Error>
878 where
879 T: ArgType<'a, Output = T>,
880 {
881 let rv = ok!(self.peek::<T>(key));
882 self.used.borrow_mut().insert(key.to_string());
883 Ok(rv)
884 }
885
886 pub fn has(&self, key: &str) -> bool {
888 self.values.contains_key(&Value::from(key))
889 }
890
891 pub fn args(&self) -> impl Iterator<Item = &str> {
893 self.values.iter().filter_map(|x| x.0.as_str())
894 }
895
896 pub fn assert_all_used(&self) -> Result<(), Error> {
898 let used = self.used.borrow();
899 for key in self.values.keys() {
900 if let Some(key) = key.as_str() {
901 if !used.contains(key) {
902 return Err(Error::new(
903 ErrorKind::TooManyArguments,
904 format!("unknown keyword argument '{}'", key),
905 ));
906 }
907 } else {
908 return Err(Error::new(
909 ErrorKind::InvalidOperation,
910 "non string keys passed to kwargs",
911 ));
912 }
913 }
914 Ok(())
915 }
916}
917
918impl FromIterator<(String, Value)> for Kwargs {
919 fn from_iter<T>(iter: T) -> Self
920 where
921 T: IntoIterator<Item = (String, Value)>,
922 {
923 Kwargs::new(Arc::new(KwargsValues(
924 iter.into_iter().map(|(k, v)| (Value::from(k), v)).collect(),
925 )))
926 }
927}
928
929impl<'a> FromIterator<(&'a str, Value)> for Kwargs {
930 fn from_iter<T>(iter: T) -> Self
931 where
932 T: IntoIterator<Item = (&'a str, Value)>,
933 {
934 Kwargs::new(Arc::new(KwargsValues(
935 iter.into_iter().map(|(k, v)| (Value::from(k), v)).collect(),
936 )))
937 }
938}
939
940impl From<Kwargs> for Value {
941 fn from(value: Kwargs) -> Self {
942 Value::from_dyn_object(value.values)
943 }
944}
945
946impl TryFrom<Value> for Kwargs {
947 type Error = Error;
948
949 fn try_from(value: Value) -> Result<Self, Self::Error> {
950 match value.0 {
951 ValueRepr::Undefined => Ok(Kwargs::new(Default::default())),
952 ValueRepr::Object(_) => {
953 Kwargs::extract(&value).ok_or_else(|| Error::from(ErrorKind::InvalidOperation))
954 }
955 _ => Err(Error::from(ErrorKind::InvalidOperation)),
956 }
957 }
958}
959
960impl<'a> ArgType<'a> for Value {
961 type Output = Self;
962
963 fn from_state_and_value(
964 _state: Option<&'a State>,
965 value: Option<&'a Value>,
966 ) -> Result<(Self::Output, usize), Error> {
967 Ok((ok!(Self::from_value(value)), 1))
968 }
969
970 fn from_value(value: Option<&'a Value>) -> Result<Self, Error> {
971 match value {
972 Some(value) => Ok(value.clone()),
973 None => Err(Error::from(ErrorKind::MissingArgument)),
974 }
975 }
976
977 fn from_value_owned(value: Value) -> Result<Self, Error> {
978 Ok(value)
979 }
980}
981
982impl<'a> ArgType<'a> for String {
983 type Output = Self;
984
985 fn from_value(value: Option<&'a Value>) -> Result<Self, Error> {
986 match value {
987 Some(value) => {
988 if value.is_kwargs() {
989 return Err(Error::new(
990 ErrorKind::InvalidOperation,
991 "cannot convert kwargs to string",
992 ));
993 }
994 Ok(value.to_string())
995 }
996 None => Err(Error::from(ErrorKind::MissingArgument)),
997 }
998 }
999
1000 fn from_value_owned(value: Value) -> Result<Self, Error> {
1001 Ok(value.to_string())
1002 }
1003}
1004
1005impl<'a, T: ArgType<'a, Output = T>> ArgType<'a> for Vec<T> {
1006 type Output = Vec<T>;
1007
1008 fn from_value(value: Option<&'a Value>) -> Result<Self, Error> {
1009 match value {
1010 None => Ok(Vec::new()),
1011 Some(value) => {
1012 let iter = ok!(value
1013 .as_object()
1014 .filter(|x| matches!(x.repr(), ObjectRepr::Seq | ObjectRepr::Iterable))
1015 .and_then(|x| x.try_iter())
1016 .ok_or_else(|| { Error::new(ErrorKind::InvalidOperation, "not iterable") }));
1017 let mut rv = Vec::new();
1018 for value in iter {
1019 rv.push(ok!(T::from_value_owned(value)));
1020 }
1021 Ok(rv)
1022 }
1023 }
1024 }
1025
1026 fn from_value_owned(value: Value) -> Result<Self, Error> {
1027 let iter = ok!(value
1028 .as_object()
1029 .filter(|x| matches!(x.repr(), ObjectRepr::Seq | ObjectRepr::Iterable))
1030 .and_then(|x| x.try_iter())
1031 .ok_or_else(|| { Error::new(ErrorKind::InvalidOperation, "not iterable") }));
1032 let mut rv = Vec::new();
1033 for value in iter {
1034 rv.push(ok!(T::from_value_owned(value)));
1035 }
1036 Ok(rv)
1037 }
1038}
1039
1040impl<'a> ArgType<'a> for DynObject {
1041 type Output = Self;
1042
1043 fn from_value(value: Option<&'a Value>) -> Result<Self, Error> {
1044 value
1045 .ok_or_else(|| Error::from(ErrorKind::MissingArgument))
1046 .and_then(|v| Self::from_value_owned(v.clone()))
1047 }
1048
1049 fn from_value_owned(value: Value) -> Result<Self, Error> {
1050 value
1051 .as_object()
1052 .cloned()
1053 .ok_or_else(|| Error::new(ErrorKind::InvalidOperation, "not an object"))
1054 }
1055}
1056
1057impl From<Value> for String {
1058 fn from(val: Value) -> Self {
1059 val.to_string()
1060 }
1061}
1062
1063impl From<usize> for Value {
1064 fn from(val: usize) -> Self {
1065 Value::from(val as u64)
1066 }
1067}
1068
1069impl From<isize> for Value {
1070 fn from(val: isize) -> Self {
1071 Value::from(val as i64)
1072 }
1073}
1074
1075impl<I: Into<Value>> From<Option<I>> for Value {
1076 fn from(value: Option<I>) -> Self {
1077 match value {
1078 Some(value) => value.into(),
1079 None => Value::from(()),
1080 }
1081 }
1082}
1083
1084#[cfg(test)]
1085mod tests {
1086 use super::*;
1087
1088 #[test]
1089 fn test_as_f64() {
1090 let v = Value::from(42u32);
1091 let f: f64 = v.try_into().unwrap();
1092 assert_eq!(f, 42.0);
1093 let v = Value::from(42.5);
1094 let f: f64 = v.try_into().unwrap();
1095 assert_eq!(f, 42.5);
1096 }
1097
1098 #[test]
1099 fn test_split_kwargs() {
1100 let args = [
1101 Value::from(42),
1102 Value::from(true),
1103 Value::from(Kwargs::from_iter([
1104 ("foo", Value::from(1)),
1105 ("bar", Value::from(2)),
1106 ])),
1107 ];
1108 let (args, kwargs) = from_args::<(&[Value], Kwargs)>(&args).unwrap();
1109 assert_eq!(args, &[Value::from(42), Value::from(true)]);
1110 assert_eq!(kwargs.get::<Value>("foo").unwrap(), Value::from(1));
1111 assert_eq!(kwargs.get::<Value>("bar").unwrap(), Value::from(2));
1112 }
1113
1114 #[test]
1115 fn test_kwargs_fails_string_conversion() {
1116 let kwargs = Kwargs::from_iter([("foo", Value::from(1)), ("bar", Value::from(2))]);
1117 let args = [Value::from(kwargs)];
1118
1119 let result = from_args::<(String,)>(&args);
1120 assert!(result.is_err());
1121 assert_eq!(
1122 result.unwrap_err().to_string(),
1123 "invalid operation: cannot convert kwargs to string"
1124 );
1125
1126 let result = from_args::<(Cow<str>,)>(&args);
1127 assert!(result.is_err());
1128 assert_eq!(
1129 result.unwrap_err().to_string(),
1130 "invalid operation: cannot convert kwargs to string"
1131 );
1132 }
1133
1134 #[test]
1135 fn test_optional_none() {
1136 let (one,) = from_args::<(Option<i32>,)>(args!(None::<i32>)).unwrap();
1137 assert!(one.is_none());
1138 let (one,) = from_args::<(Option<i32>,)>(args!(Some(Value::UNDEFINED))).unwrap();
1139 assert!(one.is_none());
1140 }
1141}