mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-06 17:34:25 +00:00
feat(str): add Str::from_str_in and Ident::from_str_in methods (#23767)
Part of #23043. Add 2 new methods: - `Str::from_str_in` - `Ident::from_str_in` Both take a `&str`, allocate it in arena, and return a `Str<'a>` / `Ident<'a>`. Both take a `&A where A: GetAllocator`, so can be passed any type which implements `GetAllocator` e.g. `ParserImpl`, `TraverseCtx` (same as `Box::new_in`, `Vec::new_in` etc).
This commit is contained in:
1 parent
7537c582e0
commit
2580eda2a7
2 files changed
+74
-2
No files matched your search
@@ -11,7 +11,8 @@ use std::{
|
||||
};
|
||||
|
||||
use oxc_allocator::{
|
||||
Allocator, ArenaStringBuilder, CloneIn, Dummy, FromIn, IdentBuildHasher, ident_hash,
|
||||
Allocator, ArenaStringBuilder, CloneIn, Dummy, FromIn, GetAllocator, IdentBuildHasher,
|
||||
ident_hash,
|
||||
};
|
||||
#[cfg(feature = "serialize")]
|
||||
use oxc_estree::{ESTree, JsonSafeString, Serializer as ESTreeSerializer};
|
||||
@@ -129,6 +130,12 @@ pub const fn new_const_ident(s: &str) -> Ident<'_> {
|
||||
}
|
||||
|
||||
impl<'a> Ident<'a> {
|
||||
/// Allocate provided `&str` into arena, and return an [`Ident<'a>`].
|
||||
#[inline]
|
||||
pub fn from_str_in<A: GetAllocator<'a>>(s: &str, allocator: &A) -> Self {
|
||||
new_const_ident(allocator.allocator().alloc_str(s))
|
||||
}
|
||||
|
||||
/// Create an [`Ident`] from raw components.
|
||||
///
|
||||
/// # SAFETY
|
||||
@@ -705,6 +712,32 @@ mod test {
|
||||
assert_eq!(IDENT.as_str(), "hello");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[expect(clippy::items_after_statements)]
|
||||
fn ident_from_str_in() {
|
||||
let allocator = Allocator::new();
|
||||
let allocator: &Allocator = &allocator;
|
||||
|
||||
// Pass an actual `Allocator`
|
||||
let ident = Ident::from_str_in("world", &allocator);
|
||||
assert_eq!(ident.as_str(), "world");
|
||||
assert_eq!(ident, Ident::from("world"));
|
||||
|
||||
// Pass a struct which implements `GetAllocator`
|
||||
struct Wrapper<'a>(&'a Allocator);
|
||||
|
||||
impl<'a> GetAllocator<'a> for Wrapper<'a> {
|
||||
fn allocator(&self) -> &'a Allocator {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
let wrapper = Wrapper(allocator);
|
||||
let ident = Ident::from_str_in("hello", &wrapper);
|
||||
assert_eq!(ident.as_str(), "hello");
|
||||
assert_eq!(ident, Ident::from("hello"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arena_ident_hashmap() {
|
||||
let allocator = Allocator::new();
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::{
|
||||
ops::Deref,
|
||||
};
|
||||
|
||||
use oxc_allocator::{Allocator, ArenaStringBuilder, CloneIn, Dummy, FromIn};
|
||||
use oxc_allocator::{Allocator, ArenaStringBuilder, CloneIn, Dummy, FromIn, GetAllocator};
|
||||
#[cfg(feature = "serialize")]
|
||||
use oxc_estree::{ESTree, Serializer as ESTreeSerializer};
|
||||
#[cfg(feature = "serialize")]
|
||||
@@ -36,6 +36,12 @@ impl Str<'static> {
|
||||
}
|
||||
|
||||
impl<'a> Str<'a> {
|
||||
/// Allocate provided `&str` into arena, and return a [`Str<'a>`].
|
||||
#[inline]
|
||||
pub fn from_str_in<A: GetAllocator<'a>>(s: &str, allocator: &A) -> Self {
|
||||
Self(allocator.allocator().alloc_str(s))
|
||||
}
|
||||
|
||||
/// Borrow a string slice.
|
||||
#[expect(clippy::inline_always)]
|
||||
#[inline(always)] // Because this is a no-op
|
||||
@@ -330,3 +336,36 @@ macro_rules! format_str {
|
||||
Str::from(s)
|
||||
}}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use oxc_allocator::Allocator;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[expect(clippy::items_after_statements)]
|
||||
fn str_from_str_in() {
|
||||
let allocator = Allocator::new();
|
||||
let allocator = &allocator;
|
||||
|
||||
// Pass an actual `Allocator`
|
||||
let s = Str::from_str_in("world", &allocator);
|
||||
assert_eq!(s.as_str(), "world");
|
||||
assert_eq!(s, Str::from("world"));
|
||||
|
||||
// Pass a struct which implements `GetAllocator`
|
||||
struct Wrapper<'a>(&'a Allocator);
|
||||
|
||||
impl<'a> GetAllocator<'a> for Wrapper<'a> {
|
||||
fn allocator(&self) -> &'a Allocator {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
let wrapper = Wrapper(allocator);
|
||||
let s = Str::from_str_in("hello", &wrapper);
|
||||
assert_eq!(s.as_str(), "hello");
|
||||
assert_eq!(s, Str::from("hello"));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user