Add server and update cli
This commit is contained in:
parent
ec28d1d467
commit
f19037f243
13 changed files with 191 additions and 34 deletions
11
Cargo.lock
generated
11
Cargo.lock
generated
|
@ -22,6 +22,17 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "achievement-counter-server"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"achievement-counter-core",
|
||||
"anyhow",
|
||||
"chrono",
|
||||
"clap",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
members = [
|
||||
"cli",
|
||||
"core",
|
||||
"core", "server",
|
||||
]
|
||||
|
||||
[workspace.dependencies]
|
||||
anyhow = "1.0.98"
|
||||
chrono = "0.4.40"
|
||||
thiserror = "2.0.12"
|
||||
thiserror = "2.0.12"
|
||||
|
|
18
cli/src/error.rs
Normal file
18
cli/src/error.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error("Parser error")]
|
||||
Clap(#[from] clap::Error),
|
||||
#[error("Parse int error")]
|
||||
ParseIntError(#[from] std::num::ParseIntError),
|
||||
#[error("IO Error")]
|
||||
IoError(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
impl Error {
|
||||
pub fn print(&self) -> Result<(), Error> {
|
||||
match self {
|
||||
Error::Clap(x) => Ok(x.print()?),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +1,56 @@
|
|||
pub mod error;
|
||||
//mod label;
|
||||
mod record;
|
||||
|
||||
//use label::LabelArgs;
|
||||
use error::Error;
|
||||
use record::{RecordArgs,RecordAddArgs};
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use clap::{Args, CommandFactory, Parser, Subcommand};
|
||||
|
||||
use std::ffi::OsString;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(version, about, long_about = None)]
|
||||
#[command(propagate_version=true)]
|
||||
struct Cli {
|
||||
#[command(flatten)]
|
||||
add_args: Option<RecordAddArgs>,
|
||||
#[command(subcommand)]
|
||||
command: Option<Command>,
|
||||
command: Command,
|
||||
}
|
||||
#[derive(Subcommand)]
|
||||
|
||||
#[derive(Clone, Debug, Subcommand)]
|
||||
enum Command {
|
||||
//Add(RecordAddArgs),
|
||||
//Label(LabelArgs),
|
||||
Record(RecordArgs),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let cli = Cli::parse();
|
||||
match &cli.command {
|
||||
//Some(Commands::Add(x)) => x.run(),
|
||||
//Some(Commands::Label(x)) => x.run(),
|
||||
Some(Command::Record(x)) => x.run(),
|
||||
None => {unimplemented!()},
|
||||
}
|
||||
fn try_parse() -> Result<Cli, Error> {
|
||||
Ok(try_parse_from(std::env::args_os())?)
|
||||
}
|
||||
|
||||
fn try_parse_from<I, T>(itr: I) -> Result<Cli, Error>
|
||||
where I: IntoIterator<Item=T>,
|
||||
T: Into<OsString> + Clone,
|
||||
{
|
||||
let os_string_vec: Vec<OsString> = itr.into_iter().map(|x| Into::<OsString>::into(x)).collect();
|
||||
Cli::try_parse_from(os_string_vec.clone()).or_else(|err| match err.kind() {
|
||||
clap::error::ErrorKind::InvalidSubcommand => {
|
||||
try_parse_from(vec![OsString::from("record"), OsString::from("add")].into_iter().chain(os_string_vec.clone().into_iter()))
|
||||
},
|
||||
_ => Err(err)?,
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
let cli = try_parse();
|
||||
match cli {
|
||||
Err(_) => Ok(Cli::command().print_help()?),
|
||||
Ok(x) => match x.command {
|
||||
//Some(Commands::Add(x)) => x.run(),
|
||||
//Some(Commands::Label(x)) => x.run(),
|
||||
Command::Record(x) => x.run(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,37 +1,56 @@
|
|||
use achievement_counter_core::Record;
|
||||
use chrono::prelude::*;
|
||||
use clap::{Args, Subcommand};
|
||||
use crate::Error;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct RecordAddArgs {
|
||||
#[derive(Args, Clone, Debug)]
|
||||
pub struct AchievementArgValues {
|
||||
pub label: String,
|
||||
pub value: i8,
|
||||
}
|
||||
|
||||
impl FromStr for AchievementArgValues {
|
||||
type Err = Error;
|
||||
fn from_str(s: &str) -> Result<Self, Error> {
|
||||
let strvec: Vec<&str> = s.split(':').collect();
|
||||
Ok(AchievementArgValues{
|
||||
label: strvec.get(0).unwrap().to_string(),
|
||||
value: strvec.get(1).unwrap().parse()?
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Args, Clone, Debug)]
|
||||
pub struct RecordAddArgs {
|
||||
#[arg(short, long)]
|
||||
pub comment: Option<String>,
|
||||
#[arg(short, long)]
|
||||
pub time: Option<DateTime<Utc>>,
|
||||
#[arg(default_value_t = 1)]
|
||||
pub count: u8,
|
||||
//pub achievements: Vec<String>,
|
||||
}
|
||||
|
||||
impl RecordAddArgs {
|
||||
pub fn run(&self) {
|
||||
pub fn run(self) -> Result<(), Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
#[derive(Clone, Debug, Subcommand)]
|
||||
pub enum RecordCommand {
|
||||
Add(RecordAddArgs),
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
#[derive(Args, Clone, Debug)]
|
||||
pub struct RecordArgs {
|
||||
#[command(subcommand)]
|
||||
command: RecordCommand,
|
||||
}
|
||||
|
||||
impl RecordArgs {
|
||||
pub fn run(&self) {
|
||||
match &self.command {
|
||||
pub fn run(self) -> Result<(), Error> {
|
||||
match self.command {
|
||||
RecordCommand::Add(x) => x.run(),
|
||||
}
|
||||
}
|
||||
|
|
10
core/src/data/achievement.rs
Normal file
10
core/src/data/achievement.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
use super::id::*;
|
||||
|
||||
pub struct Achievement<T, U>
|
||||
where T: MayId,
|
||||
U: MayId,
|
||||
{
|
||||
id: T,
|
||||
lavel: U,
|
||||
count: i8,
|
||||
}
|
55
core/src/data/id.rs
Normal file
55
core/src/data/id.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct IdNumber(usize);
|
||||
#[derive(Debug)]
|
||||
pub struct IdString(String);
|
||||
#[derive(Debug)]
|
||||
pub struct NoId();
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum IdValue {
|
||||
Number(usize),
|
||||
String(String)
|
||||
}
|
||||
|
||||
pub trait MayId {
|
||||
fn is_id() -> bool;
|
||||
fn get_value(&self) -> Option<IdValue>;
|
||||
}
|
||||
|
||||
impl MayId for IdNumber {
|
||||
fn is_id() -> bool {
|
||||
true
|
||||
}
|
||||
fn get_value(&self) -> Option<IdValue> {
|
||||
Some(IdValue::Number(self.0))
|
||||
}
|
||||
}
|
||||
impl MayId for IdString {
|
||||
fn is_id() -> bool {
|
||||
true
|
||||
}
|
||||
fn get_value(&self) -> Option<IdValue> {
|
||||
Some(IdValue::String(self.0.clone()))
|
||||
}
|
||||
}
|
||||
impl MayId for NoId {
|
||||
fn is_id() -> bool {
|
||||
false
|
||||
}
|
||||
fn get_value(&self) -> Option<IdValue> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn parse_values() {
|
||||
assert_eq!(Some(IdValue::Number(1)), IdNumber(1).get_value());
|
||||
assert_eq!(Some(IdValue::String("Test".to_string())), IdString("Test".to_string()).get_value());
|
||||
assert_eq!(None, NoId().get_value());
|
||||
}
|
||||
}
|
9
core/src/data/mod.rs
Normal file
9
core/src/data/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
mod id;
|
||||
mod label;
|
||||
mod record;
|
||||
mod achievement;
|
||||
|
||||
pub use id::*;
|
||||
pub use label::*;
|
||||
pub use record::*;
|
||||
pub use achievement::*;
|
|
@ -1,10 +1,9 @@
|
|||
use crate::label::Label;
|
||||
use chrono::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Record {
|
||||
pub label: String,
|
||||
pub comment: String,
|
||||
pub count: u8,
|
||||
pub date: DateTime<Utc>,
|
||||
pub achievements: HashMap<String, i8>,
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
pub mod label;
|
||||
pub mod record;
|
||||
pub use self::label::Label;
|
||||
pub use self::record::Record;
|
||||
pub mod data;
|
||||
pub use self::data::Label;
|
||||
pub use self::data::Record;
|
||||
|
||||
pub fn add(left: u64, right: u64) -> u64 {
|
||||
left + right
|
||||
|
|
11
server/Cargo.toml
Normal file
11
server/Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "achievement-counter-server"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
achievement-counter-core = { path = "../core" }
|
||||
anyhow = {workspace = true}
|
||||
chrono = {workspace = true}
|
||||
clap = {version = "4.5.37", features=["derive"]}
|
||||
thiserror = {workspace = true}
|
3
server/src/main.rs
Normal file
3
server/src/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
Loading…
Add table
Reference in a new issue