hocon/options.rs
1// Copyright 2026 1o1 Co. Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8
9use std::collections::HashMap;
10use std::path::PathBuf;
11
12/// Options controlling the parse phase.
13///
14/// Construct via [`ParseOptions::defaults()`] and chain `with_*` methods.
15/// The struct literal `ParseOptions { .. }` is **not** a valid invocation —
16/// it would set `resolve_substitutions: false`, contradicting the Lightbend
17/// default of `true`. Per E12 §"Options encoding per language".
18#[derive(Debug, Clone)]
19pub struct ParseOptions {
20 /// Whether phase 2 (substitution resolution) runs immediately after parsing.
21 /// Default: `true` (Lightbend default — fused parse-and-resolve).
22 pub resolve_substitutions: bool,
23 /// User-visible source name for error messages when no file path is available.
24 /// Default: `None`.
25 pub origin_description: Option<String>,
26 /// Base directory for resolving relative include directives.
27 /// Default: `None` (current directory is used when building the internal opts).
28 pub(crate) base_dir: Option<PathBuf>,
29 /// Custom environment variable map. When `None`, the process environment is
30 /// used (gated by `ResolveOptions::use_system_environment` at resolve time).
31 pub(crate) env: Option<HashMap<String, String>>,
32}
33
34impl ParseOptions {
35 /// Return `ParseOptions` with Lightbend-equivalent defaults:
36 /// `resolve_substitutions = true`, everything else `None`.
37 pub fn defaults() -> Self {
38 ParseOptions {
39 resolve_substitutions: true,
40 origin_description: None,
41 base_dir: None,
42 env: None,
43 }
44 }
45
46 /// Return a copy with `resolve_substitutions` set to `b`.
47 pub fn with_resolve_substitutions(mut self, b: bool) -> Self {
48 self.resolve_substitutions = b;
49 self
50 }
51
52 /// Return a copy with `origin_description` set to `s`.
53 pub fn with_origin_description(mut self, s: String) -> Self {
54 self.origin_description = Some(s);
55 self
56 }
57
58 /// Return a copy with `base_dir` set to `p`.
59 pub fn with_base_dir(mut self, p: PathBuf) -> Self {
60 self.base_dir = Some(p);
61 self
62 }
63
64 /// Return a copy with a custom `env` map (overrides process environment).
65 pub fn with_env(mut self, env: HashMap<String, String>) -> Self {
66 self.env = Some(env);
67 self
68 }
69}
70
71/// Options controlling the resolve phase.
72///
73/// Construct via [`ResolveOptions::defaults()`] and chain `with_*` methods.
74///
75/// **Distinct from the internal `resolver::InternalResolveOptions`** which
76/// also carries env / base_dir / include_stack for the resolver module.
77/// Translation from `ResolveOptions` to `InternalResolveOptions` happens
78/// at the `Config::resolve` boundary (T9).
79#[derive(Debug, Clone)]
80pub struct ResolveOptions {
81 /// When `true`, substitution paths not satisfied within the config tree
82 /// fall back to process environment variables. Default: `true`.
83 pub use_system_environment: bool,
84 /// When `true`, required-but-unsatisfied substitutions are left as
85 /// placeholders instead of returning a `ResolveError`. Default: `false`.
86 pub allow_unresolved: bool,
87}
88
89impl ResolveOptions {
90 /// Return `ResolveOptions` with Lightbend-equivalent defaults:
91 /// `use_system_environment = true`, `allow_unresolved = false`.
92 pub fn defaults() -> Self {
93 ResolveOptions {
94 use_system_environment: true,
95 allow_unresolved: false,
96 }
97 }
98
99 /// Return a copy with `use_system_environment` set to `b`.
100 pub fn with_use_system_environment(mut self, b: bool) -> Self {
101 self.use_system_environment = b;
102 self
103 }
104
105 /// Return a copy with `allow_unresolved` set to `b`.
106 pub fn with_allow_unresolved(mut self, b: bool) -> Self {
107 self.allow_unresolved = b;
108 self
109 }
110}