artichoke_backend::convert

Function implicitly_convert_to_spinoso_string

Source
pub unsafe fn implicitly_convert_to_spinoso_string<'a>(
    interp: &mut Artichoke,
    value: &'a mut Value,
) -> Result<UnboxedValueGuard<'a, String>, Error>
Expand description

Attempt to implicitly convert a Value to a spinoso_string::String (Ruby String).

Attempt to extract a spinoso_string::String from the given Value by trying the following conversions:

  • If the given value is a Ruby string, return the inner byte slice.
  • If the given value is nil, return a TypeError.
  • If the given value responds to the :to_str method, call value.to_str:
    • If value.to_str raises an exception, propagate that exception.
    • If value.to_str returns a Ruby string, return the inner byte slice.
    • If value.to_str returs any other type, return a TypeError.
  • If the given value does not respond to the :to_str method, return a TypeError.

Symbols are not coerced to byte slice by this implicit conversion.

§Examples

let mut interp = artichoke_backend::interpreter()?;
// successful conversions
let mut string = interp.try_convert_mut("artichoke")?;
let mut a = interp.eval(b"class A; def to_str; 'spinoso'; end; end; A.new")?;

assert!(matches!(implicitly_convert_to_spinoso_string(&mut interp, &mut string), Ok(s) if *s == b"artichoke"[..]));
assert!(matches!(implicitly_convert_to_spinoso_string(&mut interp, &mut a), Ok(s) if *s == b"spinoso"[..]));

// failed conversions
let mut nil = Value::nil();
let mut b = interp.eval(b"class B; end; B.new")?;
let mut c = interp.eval(b"class C; def to_str; nil; end; end; C.new")?;
let mut d = interp.eval(b"class D; def to_str; 17; end; end; D.new")?;
let mut e = interp.eval(b"class E; def to_str; :artichoke; end; end; E.new")?;
let mut f = interp.eval(b"class F; def to_str; raise ArgumentError, 'not a string'; end; end; F.new")?;

assert!(implicitly_convert_to_spinoso_string(&mut interp, &mut nil).is_err());
assert!(implicitly_convert_to_spinoso_string(&mut interp, &mut b).is_err());
assert!(implicitly_convert_to_spinoso_string(&mut interp, &mut c).is_err());
assert!(implicitly_convert_to_spinoso_string(&mut interp, &mut d).is_err());
assert!(implicitly_convert_to_spinoso_string(&mut interp, &mut e).is_err());
assert!(implicitly_convert_to_spinoso_string(&mut interp, &mut f).is_err());

§Errors

This function returns an error if:

  • The given value is nil.
  • The given value is not a string and does not respond to :to_str.
  • The given value is not a string and returns a non-string value from its :to_str method.
  • The given value is not a string and raises an error in its :to_str method.

§Safety

Callers must ensure that value does not outlive the given interpreter.

If a garbage collection can possibly run between calling this function and using the returned slice, callers should convert the slice to an owned byte vec.