shape/
helpers.rs

1use super::Shape;
2
3/// [`Ref<T>`] is a placeholder for whichever reference counting wrapper type we
4/// want to define here ([`std::rc::Rc`] also works).
5///
6/// Besides allowing for cheap cloning and sharing of references to [`Shape`]
7/// subtrees, reference counting also paves the way for structural sharing of
8/// canonical shapes, which could have profound performance benefits.
9///
10/// Finally, Rust will complain about the [`Shape`] type referring to itself
11/// without indirection unless we introduce a wrapper type like [`Ref<T>`] to
12/// provide the indirection.
13pub(crate) type Ref<T> = std::sync::Arc<T>;
14pub(crate) type RefWeak<T> = std::sync::Weak<T>;
15
16/// Since we're using [`std::sync::Arc`] for reference counting, and [`Shape`]
17/// is an immutable structure, we can safely implement [`Send`] and [`Sync`] for
18/// [`Shape`].
19unsafe impl Sync for Shape {}
20unsafe impl Send for Shape {}
21
22/// Quote a string with double quotes and appropriate JSON escaping.
23pub(super) fn quote_string(s: &str) -> String {
24    serde_json_bytes::Value::String(s.into()).to_string()
25}
26
27pub(super) fn quote_non_identifier(s: &str) -> String {
28    if s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') {
29        s.to_string()
30    } else {
31        quote_string(s)
32    }
33}
34
35/// A [start..end) range of byte offsets within some source document.
36pub type OffsetRange = Option<std::ops::Range<usize>>;