hocon/value.rs
1use indexmap::IndexMap;
2
3/// Payload for an unresolved substitution placeholder. Used internally by the
4/// deferred-resolution path (E12). Not part of the stable public API — marked
5/// `#[doc(hidden)]` to exclude from rustdoc and signal non-stable visibility.
6/// The type is `pub` for technical reasons (it is a field of the public `HoconValue`
7/// enum), but no semver guarantees are made for it.
8#[doc(hidden)]
9#[derive(Debug, Clone, PartialEq)]
10pub struct PlaceholderValue {
11 /// The dot-separated substitution path (e.g. `"db.host"`).
12 pub(crate) path: String,
13 /// Whether this was an optional substitution (`${?x}` vs `${x}`).
14 pub(crate) optional: bool,
15}
16
17/// A resolved HOCON value.
18///
19/// This is the tree that [`Config`](crate::Config) wraps. You normally interact
20/// with it through the typed getters on `Config`, but it is also returned
21/// directly by [`Config::get`](crate::Config::get) and
22/// [`Config::get_list`](crate::Config::get_list).
23#[non_exhaustive]
24#[derive(Debug, Clone, PartialEq)]
25pub enum HoconValue {
26 /// An ordered map of key-value pairs (HOCON object / JSON object).
27 Object(IndexMap<String, HoconValue>),
28 /// An ordered list of values (HOCON array / JSON array).
29 Array(Vec<HoconValue>),
30 /// A leaf value (string, number, boolean, or null).
31 Scalar(ScalarValue),
32 /// An unresolved substitution placeholder. Not part of the stable public API.
33 /// Marked `#[doc(hidden)]`; callers using the fused parse path will never see
34 /// this variant. May be encountered when `allow_unresolved=true` is passed to
35 /// [`Config::resolve`](crate::Config::resolve) — check `Config::is_resolved()`
36 /// instead of matching on this variant.
37 #[doc(hidden)]
38 Placeholder(PlaceholderValue),
39}
40
41/// The type tag for a scalar value.
42#[non_exhaustive]
43#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44pub enum ScalarType {
45 /// A string value.
46 String,
47 /// A numeric value (integer or floating-point).
48 Number,
49 /// A boolean value.
50 Boolean,
51 /// An explicit null.
52 Null,
53}
54
55/// A scalar (leaf) value inside a HOCON document.
56///
57/// Stores the raw string representation alongside a type tag.
58/// Typed access (i64, f64, bool) is done by parsing `raw` on demand.
59#[non_exhaustive]
60#[derive(Debug, Clone, PartialEq)]
61pub struct ScalarValue {
62 /// The raw string as it appeared in the source (or was produced by resolution).
63 pub raw: String,
64 /// The semantic type of this scalar.
65 pub value_type: ScalarType,
66}
67
68impl ScalarValue {
69 /// Create a new scalar value with explicit type.
70 pub fn new(raw: String, value_type: ScalarType) -> Self {
71 Self { raw, value_type }
72 }
73
74 /// Create a string-typed scalar.
75 pub fn string(raw: String) -> Self {
76 Self {
77 raw,
78 value_type: ScalarType::String,
79 }
80 }
81
82 /// Create a null scalar.
83 pub fn null() -> Self {
84 Self {
85 raw: "null".to_string(),
86 value_type: ScalarType::Null,
87 }
88 }
89
90 /// Create a boolean scalar.
91 pub fn boolean(value: bool) -> Self {
92 Self {
93 raw: if value { "true" } else { "false" }.to_string(),
94 value_type: ScalarType::Boolean,
95 }
96 }
97
98 /// Create a number scalar from a raw string.
99 pub fn number(raw: String) -> Self {
100 Self {
101 raw,
102 value_type: ScalarType::Number,
103 }
104 }
105}