bazzar/api/src/opts.rs

229 lines
5.4 KiB
Rust

use config::{AppConfig, UpdateConfig};
use gumdrop::Options;
use model::Email;
pub trait ResolveDbUrl {
fn own_db_url(&self) -> Option<String>;
fn db_url(&self) -> String {
self.own_db_url()
.or_else(|| std::env::var("DATABASE_URL").ok())
.unwrap_or_else(|| String::from("postgres://postgres@localhost/bazzar"))
}
}
#[derive(Options, Debug)]
pub struct Opts {
pub help: bool,
#[options(command)]
pub cmd: Option<Command>,
}
impl UpdateConfig for Opts {
fn update_config(&self, config: &mut AppConfig) {
match &self.cmd {
None => {}
Some(cmd) => {
cmd.update_config(config);
}
}
}
}
#[derive(Options, Debug)]
pub enum Command {
#[options(help = "Run server")]
Server(ServerOpts),
#[options(help = "Migrate database")]
Migrate(MigrateOpts),
#[options(help = "Generate new salt for passwords")]
GenerateHash(GenerateHashOpts),
#[options(help = "Create new account")]
CreateAccount(CreateAccountOpts),
#[options(help = "Check mailer config")]
TestMailer(TestMailerOpts),
#[options(help = "Print config information")]
ConfigInfo(ConfigInfo),
#[options(help = "Perform all search indexing")]
ReIndex(ReIndexOpts),
}
impl UpdateConfig for Command {
fn update_config(&self, config: &mut AppConfig) {
match self {
Command::Server(opts) => {
opts.update_config(config);
}
Command::Migrate(opts) => {
opts.update_config(config);
}
Command::GenerateHash(opts) => {
opts.update_config(config);
}
Command::CreateAccount(opts) => {
opts.update_config(config);
}
Command::TestMailer(opts) => {
opts.update_config(config);
}
Command::ReIndex(..) | Command::ConfigInfo(..) => {}
}
}
}
impl Default for Command {
fn default() -> Self {
Command::Server(ServerOpts::default())
}
}
#[derive(Options, Debug)]
pub struct ReIndexOpts {
pub help: bool,
pub lang: String,
}
impl UpdateConfig for ReIndexOpts {}
#[derive(Options, Debug)]
pub struct ConfigInfo {
pub help: bool,
}
#[derive(Options, Debug)]
pub struct GenerateHashOpts {
pub help: bool,
}
impl UpdateConfig for GenerateHashOpts {}
#[derive(Options, Debug)]
pub struct ServerOpts {
pub help: bool,
pub bind: String,
pub port: u16,
pub db_url: Option<String>,
}
impl Default for ServerOpts {
fn default() -> Self {
Self {
help: false,
bind: "0.0.0.0".to_string(),
port: 8080,
db_url: None,
}
}
}
impl UpdateConfig for ServerOpts {
fn update_config(&self, config: &mut AppConfig) {
{
let web = config.web_mut();
web.set_bind(&self.bind);
web.set_port(self.port);
}
if let Some(url) = self.db_url.as_ref() {
config.database_mut().set_url(url);
}
}
}
impl ResolveDbUrl for ServerOpts {
fn own_db_url(&self) -> Option<String> {
self.db_url.as_deref().map(String::from)
}
}
#[derive(Options, Debug)]
pub struct TestMailerOpts {
pub help: bool,
#[options(help = "E-mail receiver")]
pub receiver: Option<Email>,
}
impl UpdateConfig for TestMailerOpts {
fn update_config(&self, _config: &mut AppConfig) {}
}
#[derive(Options, Debug)]
pub struct MigrateOpts {
pub help: bool,
pub db_url: Option<String>,
}
impl UpdateConfig for MigrateOpts {
fn update_config(&self, config: &mut AppConfig) {
if let Some(url) = self.db_url.as_deref() {
config.database_mut().set_url(url);
}
}
}
impl ResolveDbUrl for MigrateOpts {
fn own_db_url(&self) -> Option<String> {
self.db_url.as_deref().map(String::from)
}
}
#[derive(Debug, Options)]
pub struct CreateAccountOpts {
pub help: bool,
#[options(command)]
pub cmd: Option<CreateAccountCmd>,
}
impl UpdateConfig for CreateAccountOpts {
fn update_config(&self, config: &mut AppConfig) {
if let Some(opts) = &self.cmd {
opts.update_config(config)
};
}
}
#[derive(Debug, Options)]
pub enum CreateAccountCmd {
Admin(CreateAccountDefinition),
User(CreateAccountDefinition),
}
impl UpdateConfig for CreateAccountCmd {
fn update_config(&self, config: &mut AppConfig) {
match &self {
CreateAccountCmd::Admin(opts) => {
opts.update_config(config);
}
CreateAccountCmd::User(opts) => {
opts.update_config(config);
}
}
}
}
#[derive(Debug, Options)]
pub struct CreateAccountDefinition {
pub help: bool,
#[options(free)]
pub login: String,
#[options(free)]
pub email: String,
#[options(free)]
pub pass_file: Option<String>,
#[options(help = "Database url, it will also look for DATABASE_URL env")]
pub db_url: Option<String>,
}
impl UpdateConfig for CreateAccountDefinition {
fn update_config(&self, config: &mut AppConfig) {
if let Some(url) = self.db_url.as_deref() {
config.database_mut().set_url(url);
}
}
}
impl ResolveDbUrl for CreateAccountDefinition {
fn own_db_url(&self) -> Option<String> {
self.db_url.as_deref().map(String::from)
}
}