use crate::{
args::ArgValues,
bytecode::VM,
defer_drop,
exception_private::{ExcType, RunResult, SimpleException},
heap::HeapData,
resource::ResourceTracker,
value::Value,
};
pub fn builtin_ord(vm: &mut VM<'_, impl ResourceTracker>, args: ArgValues) -> RunResult<Value> {
let value = args.get_one_arg("ord", vm.heap)?;
defer_drop!(value, vm);
match value {
Value::InternString(string_id) => {
let s = vm.interns.get_str(*string_id);
let mut chars = s.chars();
if let (Some(c), None) = (chars.next(), chars.next()) {
Ok(Value::Int(c as i64))
} else {
let len = s.chars().count();
Err(SimpleException::new_msg(
ExcType::TypeError,
format!("ord() expected a character, but string of length {len} found"),
)
.into())
}
}
Value::Ref(id) if let HeapData::Str(s) = vm.heap.get(*id) => {
let mut chars = s.as_str().chars();
if let (Some(c), None) = (chars.next(), chars.next()) {
Ok(Value::Int(c as i64))
} else {
let len = s.as_str().chars().count();
Err(SimpleException::new_msg(
ExcType::TypeError,
format!("ord() expected a character, but string of length {len} found"),
)
.into())
}
}
_ => {
let type_name = value.py_type_name(vm);
Err(SimpleException::new_msg(
ExcType::TypeError,
format!("ord() expected string of length 1, but {type_name} found"),
)
.into())
}
}
}