Skip to main content

rig_core/client/
env.rs

1//! Reads Unicode provider configuration values from the process environment.
2//!
3//! ```no_run
4//! use rig_core::client::env;
5//!
6//! let credential = env::required("OPENAI_API_KEY")?;
7//! # let _ = credential;
8//! # Ok::<(), env::EnvError>(())
9//! ```
10
11use std::env::VarError;
12
13/// A provider's configuration could not be read from the environment.
14#[derive(Debug, thiserror::Error)]
15pub enum EnvError {
16    /// A required variable is absent, or its value is not valid Unicode.
17    #[error("environment variable `{name}` is not set or is invalid")]
18    Variable {
19        /// The variable's name.
20        name: &'static str,
21        /// The underlying lookup failure.
22        #[source]
23        source: VarError,
24    },
25    /// A variable's value is present but unusable (an unparsable URL, an
26    /// empty credential).
27    #[error("environment variable `{name}` is invalid: {detail}")]
28    Invalid {
29        /// The variable's name.
30        name: &'static str,
31        /// What is wrong with the value.
32        detail: String,
33    },
34}
35
36/// Reads a required variable, returning an error if absent or non-Unicode.
37/// Empty strings are accepted; callers validate the value.
38pub fn required(name: &'static str) -> Result<String, EnvError> {
39    std::env::var(name).map_err(|source| EnvError::Variable { name, source })
40}
41
42/// Read an optional environment variable. An absent variable is `Ok(None)`;
43/// a present one that is not valid Unicode is an error, because silently
44/// ignoring it would send a request with the wrong configuration.
45pub fn optional(name: &'static str) -> Result<Option<String>, EnvError> {
46    match std::env::var(name) {
47        Ok(value) => Ok(Some(value)),
48        Err(VarError::NotPresent) => Ok(None),
49        Err(source) => Err(EnvError::Variable { name, source }),
50    }
51}