jstring/lib.rs
1/*!
2# JavaString
3The JavaString uses short string optimizations and a lack of a "capacity"
4field to reduce struct size and heap fragmentation in certain cases.
5
6## Features
7
8- Supports String API (very little at the moment but steadily growing)
9- Smaller size than standard string (16 vs 24 bytes on 64-bit platforms)
10- String interning for up to 15 bytes on 64-bit architectures (or 7 bytes on 32-bit)
11
12## How it works
13Here's how it works:
14
151. We store `len`, the length of the string, and `data`, the pointer to the
16 string itself.
172. We maintain the invariant that `data` is a valid pointer if and only if
18 it points to something that's aligned to 2 bytes.
193. Now, any time we wanna read the string, we first check the lowest significance
20 bit on `data`, and use that to see whether or not to dereference it.
214. Since `data` only uses one bit for its flag, we can use the entire lower
22 order byte for length information when it's interned. We do this with a
23 bitshift right.
245. When interning, we have `std::mem::size_of::<usize>() * 2 - 1` bytes of space.
25 On x64, this is 15 bytes, and on 32-bit architectures, this is 7 bytes.
26*/
27
28#![allow(dead_code)]
29// #![cfg_attr(not(any(test, docs)), no_std)]
30
31extern crate alloc;
32
33pub mod raw_string;
34
35use core::ops::{Deref, DerefMut};
36use raw_string::RawJavaString;
37
38/// JavaString uses short string optimizations and a lack of a "capacity" field
39/// to reduce struct size and heap fragmentation in certain cases.
40///
41/// It allows for mutation, but not for growth without reallocation.
42pub struct JavaString {
43 data: RawJavaString,
44}
45
46impl JavaString {
47 /// Creates a new empty `JavaString`.
48 ///
49 /// Given that the `JavaString` is empty, this will not allocate any initial
50 /// buffer.
51 ///
52 /// # Examples
53 ///
54 /// Basic usage:
55 ///
56 /// ```
57 /// # use java_string::*;
58 /// let s = JavaString::new();
59 /// ```
60 pub const fn new() -> Self {
61 Self {
62 data: RawJavaString::new(),
63 }
64 }
65
66 /// Creates a new empty `JavaString`. Included for API compatibility with standard
67 /// `String` implementation.
68 ///
69 /// # Examples
70 ///
71 /// Basic usage:
72 ///
73 /// ```
74 /// let mut s = String::with_capacity(10);
75 /// ```
76 pub const fn with_capacity(_len: usize) -> Self {
77 Self::new()
78 }
79}
80
81impl Deref for JavaString {
82 type Target = str;
83 fn deref(&self) -> &str {
84 unsafe { std::str::from_utf8_unchecked(self.data.get_bytes()) }
85 }
86}
87
88impl DerefMut for JavaString {
89 fn deref_mut(&mut self) -> &mut str {
90 unsafe { std::str::from_utf8_unchecked_mut(self.data.get_bytes_mut()) }
91 }
92}