shape/
helpers.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
use super::Shape;

/// [`Ref<T>`] is a placeholder for whichever reference counting wrapper type we
/// want to define here ([`std::rc::Rc`] also works).
///
/// Besides allowing for cheap cloning and sharing of references to [`Shape`]
/// subtrees, reference counting also paves the way for structural sharing of
/// canonical shapes, which could have profound performance benefits.
///
/// Finally, Rust will complain about the [`Shape`] type referring to itself
/// without indirection unless we introduce a wrapper type like [`Ref<T>`] to
/// provide the indirection.
pub(crate) type Ref<T> = std::sync::Arc<T>;

/// Since we're using [`std::sync::Arc`] for reference counting, and [`Shape`]
/// is an immutable structure, we can safely implement [`Send`] and [`Sync`] for
/// [`Shape`].
unsafe impl Sync for Shape {}
unsafe impl Send for Shape {}

/// Quote a string with double quotes and appropriate JSON escaping.
pub(super) fn quote_string(s: &str) -> String {
    serde_json_bytes::Value::String(s.into()).to_string()
}

pub(super) fn quote_non_identifier(s: &str) -> String {
    if s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') {
        s.to_string()
    } else {
        quote_string(s)
    }
}

/// A [start..end) range of byte offsets within some source document.
pub type OffsetRange = Option<std::ops::Range<usize>>;