monty 0.0.19-beta.2

A sandboxed, snapshotable Python interpreter written in Rust.
Documentation
//! Implementation of the ord() builtin function.

use crate::{
    args::ArgValues,
    bytecode::VM,
    defer_drop,
    exception_private::{ExcType, RunResult, SimpleException},
    heap::HeapData,
    resource::ResourceTracker,
    value::Value,
};

/// Implementation of the ord() builtin function.
///
/// Returns the Unicode code point of a one-character string.
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())
        }
    }
}