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}