diff --git a/crates/rune-modules/src/process.rs b/crates/rune-modules/src/process.rs index 48e5d0c52..a10a7f770 100644 --- a/crates/rune-modules/src/process.rs +++ b/crates/rune-modules/src/process.rs @@ -75,7 +75,7 @@ impl Command { #[rune::function(instance)] fn args(&mut self, args: &[Value]) -> VmResult<()> { for arg in args { - self.inner.arg(&*vm_try!(arg.as_string())); + self.inner.arg(&*vm_try!(arg.borrow_string_ref())); } VmResult::Ok(()) diff --git a/crates/rune/src/runtime/value.rs b/crates/rune/src/runtime/value.rs index 3c578c783..97c526216 100644 --- a/crates/rune/src/runtime/value.rs +++ b/crates/rune/src/runtime/value.rs @@ -976,8 +976,17 @@ impl Value { } /// Get the value as a string. + #[deprecated( + note = "For consistency with other methods, this has been renamed Value::borrow_string_ref" + )] #[inline] pub fn as_string(&self) -> Result, RuntimeError> { + self.borrow_string_ref() + } + + /// Borrow the value of a string as a reference. + #[inline] + pub fn borrow_string_ref(&self) -> Result, RuntimeError> { let result = BorrowRef::try_map(self.inner.borrow_ref()?, |kind| match kind { ValueKind::String(string) => Some(string.as_str()), _ => None, @@ -1335,19 +1344,26 @@ impl Value { VmResult::Ok(vm_try!(Future::from_value(value))) } - /// Try to coerce value into a typed value. + /// Try to coerce value into a typed reference. #[inline] - pub fn into_any(self) -> Result + pub fn into_any_ref(self) -> Result, RuntimeError> where T: Any, { - let any = match self.inner.take()? { - ValueKind::Any(any) => any, - actual => return Err(RuntimeError::expected_any(actual.type_info())), + let result = Ref::try_map(self.into_kind_ref()?, |kind| match kind { + ValueKind::Any(any) => Some(any), + _ => None, + }); + + let any = match result { + Ok(any) => any, + Err(actual) => return Err(RuntimeError::expected_any(actual.type_info())), }; - match any.downcast::() { - Ok(any) => Ok(any), + let result = Ref::result_map(any, |any| any.downcast_borrow_ref()); + + match result { + Ok(value) => Ok(value), Err((AnyObjError::Cast, any)) => { Err(RuntimeError::from(AccessErrorKind::UnexpectedType { expected: any::type_name::().into(), @@ -1358,13 +1374,13 @@ impl Value { } } - /// Try to coerce value into a typed reference. + /// Try to coerce value into a typed mutable reference. #[inline] - pub fn into_any_ref(self) -> Result, RuntimeError> + pub fn into_any_mut(self) -> Result, RuntimeError> where T: Any, { - let result = Ref::try_map(self.into_kind_ref()?, |kind| match kind { + let result = Mut::try_map(self.into_kind_mut()?, |kind| match kind { ValueKind::Any(any) => Some(any), _ => None, }); @@ -1374,7 +1390,7 @@ impl Value { Err(actual) => return Err(RuntimeError::expected_any(actual.type_info())), }; - let result = Ref::result_map(any, |any| any.downcast_borrow_ref()); + let result = Mut::result_map(any, |any| any.downcast_borrow_mut()); match result { Ok(value) => Ok(value), @@ -1388,26 +1404,53 @@ impl Value { } } - /// Try to coerce value into a typed mutable reference. + /// Borrow the value as a typed reference. #[inline] - pub fn into_any_mut(self) -> Result, RuntimeError> + pub fn borrow_any_ref(&self) -> Result, RuntimeError> where T: Any, { - let result = Mut::try_map(self.into_kind_mut()?, |kind| match kind { - ValueKind::Any(any) => Some(any), + let result = BorrowRef::try_map(self.inner.borrow_ref()?, |kind| match kind { + ValueKind::Any(any) => any.downcast_borrow_ref().ok(), _ => None, }); - let any = match result { - Ok(any) => any, - Err(actual) => return Err(RuntimeError::expected_any(actual.type_info())), - }; + match result { + Ok(s) => Ok(s), + Err(actual) => Err(RuntimeError::expected_any(actual.type_info())), + } + } - let result = Mut::result_map(any, |any| any.downcast_borrow_mut()); + /// Borrow the value as a mutable typed reference. + #[inline] + pub fn borrow_any_mut(&self) -> Result, RuntimeError> + where + T: Any, + { + let result = BorrowMut::try_map(self.inner.borrow_mut()?, |kind| match kind { + ValueKind::Any(any) => any.downcast_borrow_mut().ok(), + _ => None, + }); match result { - Ok(value) => Ok(value), + Ok(s) => Ok(s), + Err(actual) => Err(RuntimeError::expected_any(actual.type_info())), + } + } + + /// Try to coerce value into a typed value. + #[inline] + pub fn into_any(self) -> Result + where + T: Any, + { + let any = match self.inner.take()? { + ValueKind::Any(any) => any, + actual => return Err(RuntimeError::expected_any(actual.type_info())), + }; + + match any.downcast::() { + Ok(any) => Ok(any), Err((AnyObjError::Cast, any)) => { Err(RuntimeError::from(AccessErrorKind::UnexpectedType { expected: any::type_name::().into(),