44 lines
1.3 KiB
Rust
44 lines
1.3 KiB
Rust
use fix_error::Error;
|
|
use fix_runtime::{
|
|
BytecodeReader, Machine, MachineExt, Path, Step, StrictValue, Value, VmRuntimeCtx,
|
|
VmRuntimeCtxExt, canon_path_str,
|
|
};
|
|
use gc_arena::Mutation;
|
|
|
|
pub fn to_path<'gc, M: Machine<'gc>>(
|
|
m: &mut M,
|
|
ctx: &mut impl VmRuntimeCtx,
|
|
reader: &mut BytecodeReader<'_>,
|
|
mc: &Mutation<'gc>,
|
|
) -> Step {
|
|
// coerce to path THEN TO STRING
|
|
let val = m.force_and_retry::<StrictValue>(reader, mc)?;
|
|
if let Some(Path(s)) = val.downcast::<Path>() {
|
|
return m.return_from_primop(Value::new(s), reader);
|
|
}
|
|
let Some(s) = ctx.get_string(val) else {
|
|
return m.finish_err(Error::eval_error(format!(
|
|
"cannot coerce {} to a path",
|
|
val.ty()
|
|
)));
|
|
};
|
|
if !s.starts_with('/') {
|
|
return m.finish_err(Error::eval_error(format!(
|
|
"string '{s}' doesn't represent an absolute path"
|
|
)));
|
|
}
|
|
let canon = canon_path_str(s);
|
|
let sid = ctx.intern_string(canon);
|
|
m.return_from_primop(Value::new(sid), reader)
|
|
}
|
|
|
|
pub fn is_path<'gc, M: Machine<'gc>>(
|
|
m: &mut M,
|
|
reader: &mut BytecodeReader<'_>,
|
|
mc: &Mutation<'gc>,
|
|
) -> Step {
|
|
let val = m.force_and_retry::<StrictValue>(reader, mc)?;
|
|
let is_path = val.is::<Path>();
|
|
m.return_from_primop(Value::new(is_path), reader)
|
|
}
|