Skip to content

Commit

Permalink
feat: Make conversion from Janet to i64, u64, usizeand `isize…
Browse files Browse the repository at this point in the history
…` accept when Janet is String
  • Loading branch information
GrayJack committed Dec 5, 2024
1 parent 24699c3 commit ae5e3c3
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ All notable changes to the library should be put here
- **Breaking** Refactor: Use `usize` for length/index/capacity in collections
- **Breaking** Refactor: Make `IsJanetAbstract` an unsafe trait
- **Breaking** Feat: Make `amalgation` feature enabled by default
- **Breaking** Feat: Make `#[janet_fn]` maintain the high-level function in scope
- Feat: Add `Janet::dynamic_from_cstr` constructor
- Feat: Add `JanetArgs::get_value` and `JanetArgs::get_tagged` trait methods
- Feat: Add `JanetArgs::get_or_default` trait method
Expand All @@ -32,6 +33,7 @@ All notable changes to the library should be put here
- Feat: Add conversion from `Janet` to `isize` and `usize`
- Feat: Add conversion from `isize`/`usize` to `Janet`
- Feat: Make conversion from `Janet` to `i64` and `u64` accept when Janet is Number
- Feat: Make conversion from `Janet` to `i64`, `u64`, `usize`, `isize` accept when Janet is String
- Perf: Avoid allocation in `Janet::dynamic` if the passed argument is already null terminated
- Refactor: Use default implementation on `JanetArgs` trait for most methods
- Refactor: Simplify `jpanic!` macro
Expand Down
27 changes: 20 additions & 7 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use core::{
cmp::Ordering,
ffi::{CStr, c_char},
fmt::{self, Display, Write},
num::ParseIntError,
};

#[cfg(not(feature = "std"))]
Expand Down Expand Up @@ -88,7 +89,7 @@ pub trait DeepEq<Rhs = Self> {
///
/// This error only occurs when the [`Janet`] and the type it was being converted doesn't
/// match.
#[derive(Debug, PartialEq, PartialOrd, Default)]
#[derive(Debug, PartialEq, Default)]
#[non_exhaustive]
pub enum JanetConversionError {
/// Mismatched types.
Expand All @@ -101,6 +102,7 @@ pub enum JanetConversionError {
InvalidUInt32(f64),
InvalidSSize(f64),
InvalidUSize(f64),
IntFromStr(ParseIntError),
#[default]
Other,
}
Expand All @@ -115,6 +117,12 @@ impl JanetConversionError {
}
}

impl From<ParseIntError> for JanetConversionError {
fn from(value: ParseIntError) -> Self {
Self::IntFromStr(value)
}
}

#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl error::Error for JanetConversionError {}
Expand Down Expand Up @@ -146,6 +154,9 @@ impl Display for JanetConversionError {
},
Self::InvalidSSize(bad_value) => write!(f, "Expected signed size, got {bad_value}"),
Self::InvalidUSize(bad_value) => write!(f, "Expected unsigned size, got {bad_value}"),
Self::IntFromStr(err) => {
write!(f, "Error while converting integer from string: {err}")
},
Self::Other => f.pad("Error converting Janet to concrete type"),
}
}
Expand Down Expand Up @@ -936,8 +947,9 @@ impl TryFrom<Janet> for isize {
Err(JanetConversionError::InvalidSSize(x))
}
},
TaggedJanet::String(s) => Ok(s.to_str_lossy().parse::<isize>()?),
got => Err(JanetConversionError::multi_wrong_kind(
vec![JanetType::Abstract, JanetType::Number],
vec![JanetType::Abstract, JanetType::String, JanetType::Number],
got.kind(),
)),
}
Expand Down Expand Up @@ -977,8 +989,9 @@ impl TryFrom<Janet> for usize {
Err(JanetConversionError::InvalidUSize(x))
}
},
TaggedJanet::String(s) => Ok(s.to_str_lossy().parse::<usize>()?),
got => Err(JanetConversionError::multi_wrong_kind(
vec![JanetType::Abstract, JanetType::Number],
vec![JanetType::Abstract, JanetType::String, JanetType::Number],
got.kind(),
)),
}
Expand All @@ -1004,7 +1017,6 @@ impl TryFrom<Janet> for i64 {

#[inline]
fn try_from(value: Janet) -> Result<Self, Self::Error> {
// FIXME: To have parity with C janet semantics, we have to accept JanetString as well
match value.unwrap() {
TaggedJanet::Abstract(x) => Ok(x.into_inner()?),
TaggedJanet::Number(x) => {
Expand All @@ -1014,8 +1026,9 @@ impl TryFrom<Janet> for i64 {
Err(JanetConversionError::InvalidInt32(x))
}
},
TaggedJanet::String(s) => Ok(s.to_str_lossy().parse::<i64>()?),
got => Err(JanetConversionError::multi_wrong_kind(
vec![JanetType::Abstract, JanetType::Number],
vec![JanetType::Abstract, JanetType::String, JanetType::Number],
got.kind(),
)),
}
Expand All @@ -1041,7 +1054,6 @@ impl TryFrom<Janet> for u64 {

#[inline]
fn try_from(value: Janet) -> Result<Self, Self::Error> {
// FIXME: To have parity with C janet semantics, we have to accept JanetString as well
match value.unwrap() {
TaggedJanet::Abstract(x) => Ok(x.into_inner()?),
TaggedJanet::Number(x) => {
Expand All @@ -1051,8 +1063,9 @@ impl TryFrom<Janet> for u64 {
Err(JanetConversionError::InvalidUInt32(x))
}
},
TaggedJanet::String(s) => Ok(s.to_str_lossy().parse::<u64>()?),
got => Err(JanetConversionError::multi_wrong_kind(
vec![JanetType::Abstract, JanetType::Number],
vec![JanetType::Abstract, JanetType::String, JanetType::Number],
got.kind(),
)),
}
Expand Down

0 comments on commit ae5e3c3

Please sign in to comment.