rune/modules/
any.rs

1//! Dynamic typing and type reflection.
2
3use crate as rune;
4use crate::alloc::fmt::TryWrite;
5use crate::alloc::String;
6use crate::runtime::{Formatter, Type, Value, VmResult};
7use crate::{docstring, ContextError, Hash, Module};
8
9/// Dynamic typing and type reflection.
10///
11/// # `Type`
12///
13/// Values of this type indicates the type of any dynamic value and can be
14/// constructed through the [`Type::of_val`] function.
15#[rune::module(::std::any)]
16pub fn module() -> Result<Module, ContextError> {
17    let mut m = Module::from_meta(self::module_meta)?;
18
19    m.ty::<Type>()?.docs(docstring! {
20        /// Represents a type in the Rune type system.
21    })?;
22
23    m.ty::<Hash>()?.docs(docstring! {
24        /// Represents an opaque hash in the Rune type system.
25    })?;
26
27    m.function_meta(type_of_val)?;
28    m.function_meta(type_name_of_val)?;
29    m.function_meta(format_type)?;
30    Ok(m)
31}
32
33/// Convert a value into a [`Type`] object.
34///
35/// # Examples
36///
37/// ```rune
38/// let value1 = 42;
39/// let value2 = 43;
40/// let ty1 = Type::of_val(value1);
41/// let ty2 = Type::of_val(value2);
42/// assert_eq!(ty1, ty2);
43/// ```
44#[rune::function(free, path = Type::of_val)]
45#[inline]
46fn type_of_val(value: Value) -> Type {
47    Type::new(value.type_hash())
48}
49
50/// Formatting a type.
51///
52/// # Examples
53///
54/// ```rune
55/// use std::any;
56///
57/// assert_eq!(format!("{}", any::Type::of_val(42)), "Type(0x1cad9186c9641c4f)");
58/// ```
59#[rune::function(instance, protocol = DISPLAY_FMT)]
60fn format_type(ty: Type, f: &mut Formatter) -> VmResult<()> {
61    vm_write!(f, "{:?}", ty)
62}
63
64/// Get the type name of a value.
65///
66/// # Examples
67///
68/// ```rune
69/// use std::any;
70///
71/// let value = 42;
72/// assert_eq!(any::type_name_of_val(value), "::std::i64");
73///
74/// let value = [];
75/// assert_eq!(any::type_name_of_val(value), "::std::vec::Vec");
76/// ```
77#[rune::function]
78#[inline]
79pub fn type_name_of_val(value: Value) -> VmResult<String> {
80    value.into_type_name()
81}