diff --git a/crates/oxc_allocator/src/convert.rs b/crates/oxc_allocator/src/convert.rs new file mode 100644 index 0000000000000..8bdc63a515241 --- /dev/null +++ b/crates/oxc_allocator/src/convert.rs @@ -0,0 +1,66 @@ +#![allow(clippy::inline_always)] + +use crate::{Allocator, Box}; + +/// This trait works similarly to the standard library `From` trait, It comes with a similar +/// implementation containing blanket implementation for `IntoIn`, reflective implementation and a +/// bunch of primitive conversions from Rust types to their arena equivalent. +pub trait FromIn<'a, T>: Sized { + fn from_in(value: T, alloc: &'a Allocator) -> Self; +} + +/// This trait works similarly to the standard library `Into` trait. +/// It is similar to `FromIn` is reflective, A `FromIn` implementation also implicitly implements +/// `IntoIn` for the opposite type. +pub trait IntoIn<'a, T>: Sized { + fn into_in(self, alloc: &'a Allocator) -> T; +} + +/// `FromIn` is reflective +impl<'a, T> FromIn<'a, T> for T { + #[inline(always)] + fn from_in(t: T, _: &'a Allocator) -> T { + t + } +} + +/// `FromIn` implicitly implements `IntoIn`. +impl<'a, T, U> IntoIn<'a, U> for T +where + U: FromIn<'a, T>, +{ + #[inline] + fn into_in(self, alloc: &'a Allocator) -> U { + U::from_in(self, alloc) + } +} + +// ---------------- Primitive allocations ---------------- + +impl<'a> FromIn<'a, String> for crate::String<'a> { + #[inline(always)] + fn from_in(value: String, alloc: &'a Allocator) -> Self { + crate::String::from_str_in(value.as_str(), alloc) + } +} + +impl<'a> FromIn<'a, String> for &'a str { + #[inline(always)] + fn from_in(value: String, alloc: &'a Allocator) -> Self { + crate::String::from_str_in(value.as_str(), alloc).into_bump_str() + } +} + +impl<'a, T> FromIn<'a, T> for Box<'a, T> { + #[inline(always)] + fn from_in(value: T, alloc: &'a Allocator) -> Self { + Box::new_in(value, alloc) + } +} + +impl<'a, T> FromIn<'a, Option> for Option> { + #[inline(always)] + fn from_in(value: Option, alloc: &'a Allocator) -> Self { + value.map(|it| Box::new_in(it, alloc)) + } +} diff --git a/crates/oxc_allocator/src/lib.rs b/crates/oxc_allocator/src/lib.rs index 06a73b03d49d6..a8707326c0c57 100644 --- a/crates/oxc_allocator/src/lib.rs +++ b/crates/oxc_allocator/src/lib.rs @@ -4,10 +4,13 @@ use std::{ }; mod arena; +mod convert; -pub use arena::{Box, String, Vec}; use bumpalo::Bump; +pub use arena::{Box, String, Vec}; +pub use convert::{FromIn, IntoIn}; + #[derive(Default)] pub struct Allocator { bump: Bump,