1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//! Command line argument and environment variable types and parsing.

#[derive(argh::FromArgs)]
/// Run the ActivityPub server partly implementing both C2S and S2S protocols,
/// and a testing frontend. Can be configured via environment variables (real or
/// ones from and .env file) and command line arguments. Command line arguments
/// are prioritized.
pub struct Args {
    #[argh(option, default = "get_env_var(\"BIND_ADDR\")")]
    /// the IP address and port to which the HTTP server is bound to. Can also
    /// be provided via the BIND_ADDR environment variable. E.g.
    /// "127.0.0.1:8000".
    pub bind_addr: String,
    #[argh(option, default = "get_env_var(\"ACTIVITYPUB_URL\")")]
    /// the base HTTPS URL used as the base of ActivityPub IDs, at which this
    /// server is served (hopefully via a reverse proxy). Can also be provided
    /// via the ACTIVITYPUB_URL environment variable. This cannot be changed
    /// without recreating the database, using a different one with an existing
    /// database will break things. E.g. `"https://example.com"`.
    pub activitypub_url: String,
    #[argh(option, default = "get_env_var(\"DATABASE_URL\")")]
    /// a database url this server should use for accessing its database. Can
    /// also be provided via the DATABASE_URL environment variable. Must be a
    /// postgresql URL. E.g. "postgresql://fediverse_server_db".
    pub database_url: String,
}

/// Returns the value of the environment variable, or exits the process with
/// exit code 2 (usage) and prints a help message. Used as a fallback to
/// required command line arguments.
fn get_env_var(name: &str) -> String {
    match dotenvy::var(name) {
        Ok(var) => var,
        Err(_) => {
            eprintln!("Error: missing command line argument or environment variable {name}. Try --help.");
            std::process::exit(2);
        }
    }
}