Dotenv Config
Read a project-local .env file with File::Read, decode scalar values at the boundary with Decode<T>, and reshape the result into a typed runtime config.
Source
examples/dotenv-config/.env
APP_ENV=prod
PORT=9000
DEBUG=true
APP_NAME="Rank Docs"
examples/dotenv-config/main.rank
/// Reads a project-local dotenv file through File::Read with Decode<T>
/// at the flat text boundary and reshapes it into a typed runtime config.
use std::Decode
use std::File
use std::Path
AppEnv = `dev` | `prod`
Port = 8080 | 9000
DotenvConfig = Object {
APP_ENV: AppEnv,
PORT?: Decode<Port>,
DEBUG?: Decode<bool>,
APP_NAME: string,
...: string,
}
AppConfig = Object {
name: string,
env: AppEnv,
port: number,
debug: bool,
source: Object {
path: string,
format: `dotenv`,
},
}
response = File::Read<DotenvConfig> {
path: Path::join([`.env`]),
format: `dotenv`,
}
raw = response.body
config: AppConfig = {
name: raw.APP_NAME,
env: raw.APP_ENV,
port: raw.PORT ?? 8080,
debug: raw.DEBUG ?? false,
source: {
path: response.ctx.path,
format: `dotenv`,
},
}
pub main = || config
Output
{
"name": "Rank Docs",
"env": "prod",
"port": 9000,
"debug": true,
"source": {
"path": ".env",
"format": "dotenv"
}
}
Key concepts
format: dotenv—File::Readcan decode.env-style flat text files as an explicit file dependency rather than ambient host environment.- Boundary decoding with
Decode<T>—PORT?: Decode<Port>andDEBUG?: Decode<bool>turn dotenv text into typed scalar values as the file is read. - Flat text model — each dotenv entry stays one key/value text boundary; nested objects and lists are not decoded from a single entry.
response.ctx— file provenance stays explicit, so the resulting config can still carry the source path and format.- Defaults after decode — optional decoded fields combine cleanly with
??once the boundary parsing has succeeded.
Run it
rank examples/dotenv-config