aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
blob: c72aad742e12f82f609bf11f34e798f1c842a6bb (plain)
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#![feature(iterator_try_collect, never_type)]
pub mod client;
pub mod server;

use anyhow::Result;
use clap::{Parser, Subcommand};
use client::Client;
use serde::Deserialize;
use server::server;
use std::{fs::read_to_string, net::SocketAddr, path::PathBuf};

pub type Serial = u64;

#[derive(Parser)]
struct Args {
    config: PathBuf,
    #[clap(subcommand)]
    action: Action,
}

#[derive(Subcommand)]
enum Action {
    Daemon,
    List {
        peer: Option<String>,
    },
    Restore {
        peer: String,
        id: String,
        destination: PathBuf,
    },
    Backup {
        path: PathBuf,
    },
}

#[derive(Deserialize)]
pub struct Config {
    storage: StorageConfig,
    server: ServerConfig,
    peer: Vec<PeerConfig>,
}

#[derive(Deserialize)]
pub struct PeerConfig {
    name: String,
    address: SocketAddr,
    shared_secret: String,
}

#[derive(Deserialize)]
pub struct ServerConfig {
    address: String,
}

#[derive(Deserialize)]
pub struct StorageConfig {
    root: PathBuf,
    size: u64,
    versions: usize,
    upload_cooldown: u64,
    download_cooldown: u64,
    upload_speed: usize,
    download_speed: usize,
}

fn main() -> Result<()> {
    env_logger::init_from_env("LOG");
    let args = Args::parse();

    let config = read_to_string(&args.config)?;
    let config = toml::from_str::<Config>(&config)?;

    match args.action {
        Action::Daemon => server(config.into())?,
        Action::List { peer } => {
            let peers = config.peer.iter().filter(|p| {
                if let Some(pn) = &peer {
                    pn == &p.name
                } else {
                    true
                }
            });

            for p in peers {
                println!("peer {:?}", p.name);
                let mut client = Client::new(p.address, &p.shared_secret)?;
                for (mtime, size, serial) in client.list()? {
                    println!("\tserial={serial} mtime={mtime} size={size}")
                }
                client.quit()?;
            }
        }
        Action::Restore {
            id,
            destination,
            peer,
        } => todo!(),
        Action::Backup { path } => todo!(),
    }
    Ok(())
}