combined lib/cli

This commit is contained in:
randogoth 2024-04-09 08:35:31 +03:00
parent 92c862bd4c
commit 448be74887
4 changed files with 128 additions and 21 deletions

61
Cargo.lock generated
View file

@ -2,6 +2,17 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -26,6 +37,15 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "indoc"
version = "2.0.4"
@ -54,6 +74,16 @@ dependencies = [
"scopeguard",
]
[[package]]
name = "lyagushka"
version = "1.1.0"
dependencies = [
"atty",
"pyo3",
"serde",
"serde_json",
]
[[package]]
name = "memoffset"
version = "0.9.0"
@ -101,15 +131,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "pyagushka"
version = "1.1.0"
dependencies = [
"pyo3",
"serde",
"serde_json",
]
[[package]]
name = "pyo3"
version = "0.20.2"
@ -267,6 +288,28 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-targets"
version = "0.48.5"

View file

@ -1,17 +1,11 @@
[package]
name = "pyagushka"
name = "lyagushka"
version = "1.1.0"
edition = "2021"
[lib]
name = "pyagushka"
crate-type = ["cdylib"]
[dependencies]
pyo3 = "0.20.2"
atty = "0.2.14"
pyo3 = { version = "0.20.2", features = ["extension-module"] }
serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.113"
[features]
extension-module = ["pyo3/extension-module"]
default = ["extension-module"]
serde_json = "1.0.113"

View file

@ -34,7 +34,7 @@ impl Anomaly {
}
#[pyclass]
struct Lyagushka {
pub struct Lyagushka {
dataset: Vec<i32>,
anomalies: Vec<Anomaly>,
}
@ -154,7 +154,7 @@ impl Lyagushka {
}
#[pymodule]
fn pyagushka(_py: Python, m: &PyModule) -> PyResult<()> {
fn lyagushka(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<Lyagushka>()?;
Ok(())
}

70
src/main.rs Normal file
View file

@ -0,0 +1,70 @@
use std::fs::File;
use std::io::{self, BufRead, BufReader, stdin};
use std::env;
use std::process;
use lyagushka::Lyagushka;
/// The entry point for the command-line tool that reads a dataset of integers from either a file or stdin,
/// performs cluster and gap analysis using specified parameters, and prints the results as a JSON string.
///
/// This tool expects either a filename as an argument or a list of integers piped into stdin. It also requires
/// two additional command-line arguments: a factor for adjusting clustering and gap detection thresholds,
/// and a minimum cluster size. The tool reads the dataset, performs the analysis by identifying clusters
/// and significant gaps, calculates z-scores for each, and prints the JSON-serialized results to stdout.
///
/// # Usage
/// To read from a file:
/// ```
/// cargo run -- filename.txt 0.5 2
/// ```
///
/// To read from stdin:
/// ```
/// echo "1\n2\n10\n20" | cargo run -- 0.5 2
/// ```
///
/// # Arguments
/// - A filename (if not receiving piped input) to read the dataset from.
/// - `factor`: A floating-point value used to adjust the sensitivity of cluster and gap detection.
/// - `min_cluster_size`: The minimum number of contiguous points required to be considered a cluster.
///
/// # Exit Codes
/// - `0`: Success.
/// - `1`: Incorrect usage or failure to parse the input data.
///
/// # Errors
/// This tool will exit with an error if the required arguments are not provided, if the specified file cannot be opened,
/// or if the input data cannot be parsed into integers.
///
/// # Note
/// This function does not return a value but directly exits the process in case of failure.
///
fn main() -> io::Result<()> {
let args: Vec<String> = env::args().collect();
// Input handling
let dataset: Vec<i32> = if atty::is(atty::Stream::Stdin) {
if args.len() != 4 {
eprintln!("Usage: {} <filename> <factor> <min_cluster_size>", args[0]);
process::exit(1);
}
let filename = &args[1];
let file = File::open(filename)?;
BufReader::new(file).lines().filter_map(Result::ok)
.filter_map(|line| line.trim().parse::<i32>().ok()) // Directly parse to i32
.collect()
} else {
stdin().lock().lines().filter_map(Result::ok)
.filter_map(|line| line.trim().parse::<i32>().ok()) // Directly parse to i32
.collect()
};
let factor: f32 = args[args.len() - 2].parse().expect("Factor must be a float");
let min_cluster_size: usize = args[args.len() - 1].parse().expect("Min cluster size must be an integer");
// Analysis and output
let mut zhaba = Lyagushka::new(dataset);
println!("{}", zhaba.search(factor, min_cluster_size));
Ok(())
}