omg_api/
lib.rs

1use clap::Subcommand;
2
3pub mod account;
4pub use account::Account;
5pub mod address;
6pub use address::{Address, AddressResponse, GetExpiry, GetInfo, GetPublicInfo, IsAvailable};
7pub mod dns;
8pub use dns::Dns;
9pub mod email;
10pub use email::Email;
11pub mod now;
12pub use now::Now;
13pub mod pastebin;
14pub use pastebin::Pastebin;
15pub mod purl;
16pub use purl::Purl;
17pub mod status;
18pub use status::Status;
19pub mod theme;
20pub use theme::Theme;
21pub mod web;
22pub use web::Web;
23pub mod weblog;
24pub use weblog::Weblog;
25
26fn get<T: serde::de::DeserializeOwned>(url: &str) -> Result<T, reqwest::Error> {
27    reqwest::blocking::Client::new()
28        .get(format!("https://api.omg.lol/{}", url))
29        .send()?
30        .error_for_status()?
31        .json::<T>()
32}
33
34fn get_auth<T: serde::de::DeserializeOwned>(api_key: &str, url: &str) -> Result<T, reqwest::Error> {
35    reqwest::blocking::Client::new()
36        .get(format!("https://api.omg.lol/{}", url))
37        .header(reqwest::header::AUTHORIZATION, format!("Bearer {api_key}"))
38        .send()?
39        .error_for_status()?
40        .json::<T>()
41}
42
43// TODO: gate clap derives behind crate feature, not needed for TUI/GUI
44// TODO: allow content fields for some commands to provide filepaths, using the content of the file instead
45#[derive(Subcommand)]
46pub enum Commands {
47    /// Get information and make changes to your account
48    #[clap(visible_aliases = &["ac"])]
49    Account {
50        #[clap(subcommand)]
51        command: Account,
52    },
53    /// Get information and make changes to your addresses
54    #[clap(visible_aliases = &["a"])]
55    Address {
56        #[clap(subcommand)]
57        command: Address,
58    },
59    /// Save omg.lol API key to config.toml, will prompt (vs env. var: OMGLOL_API_KEY)
60    Auth {
61        /// Linked omg.lol name for API key
62        name: String,
63    },
64    /// Get the address directory, consisting of addresses that have opted-in to be listed
65    #[clap(visible_aliases = &["dir"])]
66    Directory,
67    /// Adjust the switchboard / DNS records for your omg.lol address
68    #[clap(visible_aliases = &["d"])]
69    Dns {
70        #[clap(subcommand)]
71        command: Dns,
72    },
73    /// Manage the email configuration for an omg.lol address
74    #[clap(visible_aliases = &["e"])]
75    Email {
76        #[clap(subcommand)]
77        command: Email,
78    },
79    /// Manage your /now page
80    #[clap(visible_aliases = &["n"])]
81    Now {
82        #[clap(subcommand)]
83        command: Now,
84    },
85    /// Manage the pastebin for an omg.lol address
86    #[clap(visible_aliases = &["p"])]
87    Pastebin {
88        #[clap(subcommand)]
89        command: Pastebin,
90    },
91    /// Manage preferences for omg.lol accounts, addresses and objects
92    #[clap(visible_aliases = &["pr"])]
93    Preferences {
94        /// Account to change settings for
95        owner: String,
96        /// ID of setting to update
97        item: String,
98        /// Value to set "item" to
99        value: String,
100    },
101    /// Manage PURLs (Persistent URLs) for your omg.lol address
102    #[clap(visible_aliases = &["u"])]
103    Purl {
104        #[clap(subcommand)]
105        command: Purl,
106    },
107    /// Get service information about omg.lol
108    Service,
109    /// Manage the statuslog for an omg.lol address
110    #[clap(visible_aliases = &["s"])]
111    Status {
112        #[clap(subcommand)]
113        command: Status,
114    },
115    /// Set a default omg.lol address (and API key) from saved addresses
116    Switch {
117        /// new default omg.lol address, leave blank to list available addresses
118        address: Option<String>,
119    },
120    /// Manage omg.lol profile themes
121    #[clap(visible_aliases = &["t"])]
122    Theme {
123        #[clap(subcommand)]
124        command: Theme,
125    },
126    /// Manage profile page and web stuff for an omg.lol address
127    #[clap(visible_aliases = &["w"])]
128    Web {
129        #[clap(subcommand)]
130        command: Web,
131    },
132    /// Manage the weblog for an omg.lol address
133    #[clap(visible_aliases = &["b"])]
134    Weblog {
135        #[clap(subcommand)]
136        command: Weblog,
137    },
138}
139
140impl Commands {
141    // TBD: Is there a more idiomatic / succinct approach to this?
142    pub fn process(
143        &self,
144        _address: &str,
145        api_key: &str,
146    ) -> Result<CommandResponse, reqwest::Error> {
147        match self {
148            Commands::Account { command } => {
149                command.process();
150                Ok(CommandResponse::Todo(()))
151            }
152            Commands::Address { command } => {
153                Ok(CommandResponse::Address(command.process(api_key)?))
154            }
155            Commands::Auth { name } => unreachable!("{name}"),
156            Commands::Directory => todo!(),
157            Commands::Dns { command } => todo!("{command:?}"),
158            Commands::Email { command } => todo!("{command:?}"),
159            Commands::Now { command } => todo!("{command:?}"),
160            Commands::Pastebin { command } => todo!("{command:?}"),
161            Commands::Preferences { owner, item, value } => todo!("{owner}, {item}, {value}"),
162            Commands::Purl { command } => todo!("{command:?}"),
163            Commands::Service => todo!(),
164            Commands::Status { command } => todo!("{command:?}"),
165            Commands::Switch { address: _ } => todo!(),
166            Commands::Theme { command } => todo!("{command:?}"),
167            Commands::Web { command } => todo!("{command:?}"),
168            Commands::Weblog { command } => todo!("{command:?}"),
169        }
170    }
171}
172
173#[derive(Debug)]
174pub enum CommandResponse {
175    Todo(()),
176    Address(AddressResponse),
177}