Fix type name display.
This commit is contained in:
parent
419ee45043
commit
345a060672
@ -13,6 +13,7 @@ Bug fixes
|
|||||||
* Variables introduced inside `try` blocks are now properly cleaned up upon an exception.
|
* Variables introduced inside `try` blocks are now properly cleaned up upon an exception.
|
||||||
* Off-by-one error in character positions after a comment line is now fixed.
|
* Off-by-one error in character positions after a comment line is now fixed.
|
||||||
* Globally-defined constants are now encapsulated correctly inside a loaded module and no longer spill across call boundaries.
|
* Globally-defined constants are now encapsulated correctly inside a loaded module and no longer spill across call boundaries.
|
||||||
|
* Type names display is fixed.
|
||||||
|
|
||||||
Script-breaking changes
|
Script-breaking changes
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
//! Module defining the public API of the Rhai engine.
|
//! Module defining the public API of the Rhai engine.
|
||||||
|
|
||||||
|
pub mod type_names;
|
||||||
|
|
||||||
pub mod eval;
|
pub mod eval;
|
||||||
|
|
||||||
pub mod run;
|
pub mod run;
|
||||||
|
132
src/api/type_names.rs
Normal file
132
src/api/type_names.rs
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
use crate::{
|
||||||
|
Engine, ExclusiveRange, FnPtr, ImmutableString, InclusiveRange, Instant, Position, RhaiError,
|
||||||
|
ERR,
|
||||||
|
};
|
||||||
|
use std::any::type_name;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
|
/// Map the name of a standard type into a friendly form.
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
fn map_std_type_name(name: &str, shorthands: bool) -> &str {
|
||||||
|
let name = name.trim();
|
||||||
|
|
||||||
|
if name == type_name::<String>() {
|
||||||
|
return if shorthands { "string" } else { "String" };
|
||||||
|
}
|
||||||
|
if name == type_name::<ImmutableString>() || name == "ImmutableString" {
|
||||||
|
return if shorthands {
|
||||||
|
"string"
|
||||||
|
} else {
|
||||||
|
"ImmutableString"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if name == type_name::<&str>() {
|
||||||
|
return if shorthands { "string" } else { "&str" };
|
||||||
|
}
|
||||||
|
#[cfg(feature = "decimal")]
|
||||||
|
if name == type_name::<rust_decimal::Decimal>() {
|
||||||
|
return if shorthands { "decimal" } else { "Decimal" };
|
||||||
|
}
|
||||||
|
if name == type_name::<FnPtr>() || name == "FnPtr" {
|
||||||
|
return if shorthands { "Fn" } else { "FnPtr" };
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
if name == type_name::<crate::Array>() || name == "Array" {
|
||||||
|
return if shorthands { "array" } else { "Array" };
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
if name == type_name::<crate::Blob>() || name == "Blob" {
|
||||||
|
return if shorthands { "blob" } else { "Blob" };
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
if name == type_name::<crate::Map>() || name == "Map" {
|
||||||
|
return if shorthands { "map" } else { "Map" };
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
|
if name == type_name::<Instant>() || name == "Instant" {
|
||||||
|
return if shorthands { "timestamp" } else { "Instant" };
|
||||||
|
}
|
||||||
|
if name == type_name::<ExclusiveRange>() || name == "ExclusiveRange" {
|
||||||
|
return if shorthands {
|
||||||
|
"range"
|
||||||
|
} else if cfg!(feature = "only_i32") {
|
||||||
|
"Range<i32>"
|
||||||
|
} else {
|
||||||
|
"Range<i64>"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if name == type_name::<InclusiveRange>() || name == "InclusiveRange" {
|
||||||
|
return if shorthands {
|
||||||
|
"range="
|
||||||
|
} else if cfg!(feature = "only_i32") {
|
||||||
|
"RangeInclusive<i32>"
|
||||||
|
} else {
|
||||||
|
"RangeInclusive<i64>"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if name.starts_with("rhai::") {
|
||||||
|
map_std_type_name(&name[6..], shorthands)
|
||||||
|
} else {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Engine {
|
||||||
|
/// Pretty-print a type name.
|
||||||
|
///
|
||||||
|
/// If a type is registered via [`register_type_with_name`][Engine::register_type_with_name],
|
||||||
|
/// the type name provided for the registration will be used.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the type name is `&mut`.
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub fn map_type_name<'a>(&'a self, name: &'a str) -> &'a str {
|
||||||
|
self.type_names
|
||||||
|
.get(name)
|
||||||
|
.map(|s| s.as_str())
|
||||||
|
.unwrap_or_else(|| map_std_type_name(name, true))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Format a type name.
|
||||||
|
///
|
||||||
|
/// If a type is registered via [`register_type_with_name`][Engine::register_type_with_name],
|
||||||
|
/// the type name provided for the registration will be used.
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub(crate) fn format_type_name<'a>(&'a self, name: &'a str) -> std::borrow::Cow<'a, str> {
|
||||||
|
if name.starts_with("&mut ") {
|
||||||
|
let x = &name[5..];
|
||||||
|
let r = self.format_type_name(x);
|
||||||
|
return if x != r {
|
||||||
|
format!("&mut {}", r).into()
|
||||||
|
} else {
|
||||||
|
name.into()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
self.type_names
|
||||||
|
.get(name)
|
||||||
|
.map(|s| s.as_str())
|
||||||
|
.unwrap_or_else(|| match name {
|
||||||
|
"INT" => return type_name::<crate::INT>(),
|
||||||
|
#[cfg(not(feature = "no_float"))]
|
||||||
|
"FLOAT" => return type_name::<crate::FLOAT>(),
|
||||||
|
_ => map_std_type_name(name, false),
|
||||||
|
})
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Make a `Box<`[`EvalAltResult<ErrorMismatchDataType>`][ERR::ErrorMismatchDataType]`>`.
|
||||||
|
#[inline(never)]
|
||||||
|
#[must_use]
|
||||||
|
pub(crate) fn make_type_mismatch_err<T>(&self, typ: &str, pos: Position) -> RhaiError {
|
||||||
|
ERR::ErrorMismatchDataType(self.map_type_name(type_name::<T>()).into(), typ.into(), pos)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}
|
@ -4,15 +4,14 @@ use crate::api::custom_syntax::CustomSyntax;
|
|||||||
use crate::func::native::{OnDebugCallback, OnParseTokenCallback, OnPrintCallback, OnVarCallback};
|
use crate::func::native::{OnDebugCallback, OnParseTokenCallback, OnPrintCallback, OnVarCallback};
|
||||||
use crate::packages::{Package, StandardPackage};
|
use crate::packages::{Package, StandardPackage};
|
||||||
use crate::tokenizer::Token;
|
use crate::tokenizer::Token;
|
||||||
use crate::types::dynamic::{map_std_type_name, Union};
|
use crate::types::dynamic::{ Union};
|
||||||
use crate::{
|
use crate::{
|
||||||
Dynamic, Identifier, ImmutableString, Module, Position, RhaiError, RhaiResult, Shared,
|
Dynamic, Identifier, ImmutableString, Module, Position, RhaiResult, Shared,
|
||||||
StaticVec, ERR,
|
StaticVec,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
use std::{
|
use std::{
|
||||||
any::type_name,
|
|
||||||
collections::{BTreeMap, BTreeSet},
|
collections::{BTreeMap, BTreeSet},
|
||||||
fmt,
|
fmt,
|
||||||
num::NonZeroU8,
|
num::NonZeroU8,
|
||||||
@ -337,59 +336,4 @@ impl Engine {
|
|||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pretty-print a type name.
|
|
||||||
///
|
|
||||||
/// If a type is registered via [`register_type_with_name`][Engine::register_type_with_name],
|
|
||||||
/// the type name provided for the registration will be used.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if the type name is `&mut`.
|
|
||||||
#[inline]
|
|
||||||
#[must_use]
|
|
||||||
pub fn map_type_name<'a>(&'a self, name: &'a str) -> &'a str {
|
|
||||||
self.type_names
|
|
||||||
.get(name)
|
|
||||||
.map(|s| s.as_str())
|
|
||||||
.unwrap_or_else(|| map_std_type_name(name, true))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Format a type name.
|
|
||||||
///
|
|
||||||
/// If a type is registered via [`register_type_with_name`][Engine::register_type_with_name],
|
|
||||||
/// the type name provided for the registration will be used.
|
|
||||||
#[cfg(feature = "metadata")]
|
|
||||||
#[inline]
|
|
||||||
#[must_use]
|
|
||||||
pub(crate) fn format_type_name<'a>(&'a self, name: &'a str) -> std::borrow::Cow<'a, str> {
|
|
||||||
if name.starts_with("&mut ") {
|
|
||||||
let x = &name[5..];
|
|
||||||
let r = self.format_type_name(x);
|
|
||||||
return if x != r {
|
|
||||||
format!("&mut {}", r).into()
|
|
||||||
} else {
|
|
||||||
name.into()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
self.type_names
|
|
||||||
.get(name)
|
|
||||||
.map(|s| s.as_str())
|
|
||||||
.unwrap_or_else(|| match name {
|
|
||||||
"INT" => return type_name::<crate::INT>(),
|
|
||||||
#[cfg(not(feature = "no_float"))]
|
|
||||||
"FLOAT" => return type_name::<crate::FLOAT>(),
|
|
||||||
_ => map_std_type_name(name, false),
|
|
||||||
})
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Make a `Box<`[`EvalAltResult<ErrorMismatchDataType>`][ERR::ErrorMismatchDataType]`>`.
|
|
||||||
#[inline]
|
|
||||||
#[must_use]
|
|
||||||
pub(crate) fn make_type_mismatch_err<T>(&self, typ: &str, pos: Position) -> RhaiError {
|
|
||||||
ERR::ErrorMismatchDataType(self.map_type_name(type_name::<T>()).into(), typ.into(), pos)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,8 @@ pub use eval::EvalContext;
|
|||||||
pub use func::{NativeCallContext, RegisterNativeFunction};
|
pub use func::{NativeCallContext, RegisterNativeFunction};
|
||||||
pub use module::{FnNamespace, Module};
|
pub use module::{FnNamespace, Module};
|
||||||
pub use tokenizer::Position;
|
pub use tokenizer::Position;
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
|
pub use types::Instant;
|
||||||
pub use types::{
|
pub use types::{
|
||||||
Dynamic, EvalAltResult, FnPtr, ImmutableString, LexError, ParseError, ParseErrorType, Scope,
|
Dynamic, EvalAltResult, FnPtr, ImmutableString, LexError, ParseError, ParseErrorType, Scope,
|
||||||
};
|
};
|
||||||
|
@ -16,11 +16,11 @@ use std::{
|
|||||||
|
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(target_family = "wasm"))]
|
#[cfg(not(target_family = "wasm"))]
|
||||||
use std::time::Instant;
|
pub use std::time::Instant;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(target_family = "wasm")]
|
#[cfg(target_family = "wasm")]
|
||||||
use instant::Instant;
|
pub use instant::Instant;
|
||||||
|
|
||||||
/// The message: data type was checked
|
/// The message: data type was checked
|
||||||
const CHECKED: &str = "data type was checked";
|
const CHECKED: &str = "data type was checked";
|
||||||
@ -543,74 +543,6 @@ impl Hash for Dynamic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Map the name of a standard type into a friendly form.
|
|
||||||
#[inline]
|
|
||||||
#[must_use]
|
|
||||||
pub(crate) fn map_std_type_name(name: &str, shorthands: bool) -> &str {
|
|
||||||
let name = name.trim();
|
|
||||||
|
|
||||||
if name.starts_with("rhai::") {
|
|
||||||
return map_std_type_name(&name[6..], shorthands);
|
|
||||||
}
|
|
||||||
|
|
||||||
if name == type_name::<String>() {
|
|
||||||
return if shorthands { "string" } else { "String" };
|
|
||||||
}
|
|
||||||
if name == type_name::<ImmutableString>() {
|
|
||||||
return if shorthands {
|
|
||||||
"string"
|
|
||||||
} else {
|
|
||||||
"ImmutableString"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if name == type_name::<&str>() {
|
|
||||||
return if shorthands { "string" } else { "&str" };
|
|
||||||
}
|
|
||||||
#[cfg(feature = "decimal")]
|
|
||||||
if name == type_name::<rust_decimal::Decimal>() {
|
|
||||||
return if shorthands { "decimal" } else { "Decimal" };
|
|
||||||
}
|
|
||||||
if name == type_name::<FnPtr>() {
|
|
||||||
return if shorthands { "Fn" } else { "FnPtr" };
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
if name == type_name::<crate::Array>() {
|
|
||||||
return if shorthands { "array" } else { "Array" };
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
if name == type_name::<crate::Blob>() {
|
|
||||||
return if shorthands { "blob" } else { "Blob" };
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
if name == type_name::<crate::Map>() {
|
|
||||||
return if shorthands { "map" } else { "Map" };
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "no_std"))]
|
|
||||||
if name == type_name::<Instant>() {
|
|
||||||
return if shorthands { "timestamp" } else { "Instant" };
|
|
||||||
}
|
|
||||||
if name == type_name::<ExclusiveRange>() || name == "ExclusiveRange" {
|
|
||||||
return if shorthands {
|
|
||||||
"range"
|
|
||||||
} else if cfg!(feature = "only_i32") {
|
|
||||||
"Range<i32>"
|
|
||||||
} else {
|
|
||||||
"Range<i64>"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if name == type_name::<InclusiveRange>() || name == "InclusiveRange" {
|
|
||||||
return if shorthands {
|
|
||||||
"range="
|
|
||||||
} else if cfg!(feature = "only_i32") {
|
|
||||||
"RangeInclusive<i32>"
|
|
||||||
} else {
|
|
||||||
"RangeInclusive<i64>"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
name
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Dynamic {
|
impl fmt::Display for Dynamic {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
|
@ -9,6 +9,8 @@ pub mod parse_error;
|
|||||||
pub mod scope;
|
pub mod scope;
|
||||||
|
|
||||||
pub use dynamic::Dynamic;
|
pub use dynamic::Dynamic;
|
||||||
|
#[cfg(not(feature = "no_std"))]
|
||||||
|
pub use dynamic::Instant;
|
||||||
pub use error::EvalAltResult;
|
pub use error::EvalAltResult;
|
||||||
pub use fn_ptr::FnPtr;
|
pub use fn_ptr::FnPtr;
|
||||||
pub use immutable_string::ImmutableString;
|
pub use immutable_string::ImmutableString;
|
||||||
|
Loading…
Reference in New Issue
Block a user