Turned the repo into a Cargo workspace, with r701 as a member
Check, format and test / build (push) Successful in 44s
Check, format and test / build (push) Successful in 44s
Moving the library into its own r701/ directory makes room for the Tauri GUI client (Oxibadge) to be added as a sibling workspace member in a following commit. edition/license/repository are now inherited from the new workspace root instead of being duplicated per member. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+5
-25
@@ -1,28 +1,8 @@
|
||||
[package]
|
||||
name = "r701"
|
||||
version = "0.2.0"
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["r701"]
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
license = "AGPL-3.0-or-later"
|
||||
repository = "https://git.nicolabelluti.me/nicolabelluti/r701"
|
||||
|
||||
[dependencies]
|
||||
async-stream = "0.3.6"
|
||||
chrono = { version = "0.4.38", default-features = false, features = ["clock"] }
|
||||
serde = { version = "1.0.203", default-features = false, features = ["derive"], optional = true }
|
||||
tokio = { version = "1.53.1", default-features = false, features = ["net", "io-util", "sync"] }
|
||||
tokio-stream = { version = "0.1.19", default-features = false }
|
||||
|
||||
[features]
|
||||
serde = ["chrono/serde", "dep:serde"]
|
||||
|
||||
[lints.rust]
|
||||
unsafe_code = "forbid"
|
||||
|
||||
[lints.clippy]
|
||||
unwrap_used = "deny"
|
||||
enum_glob_use = { level = "deny", priority = 1 }
|
||||
pedantic = { level = "deny", priority = -1 }
|
||||
nursery = { level = "deny", priority = -1 }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1.53.1", features = ["rt", "macros", "net"] }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div align="center">
|
||||
|
||||
# R701 🕰️
|
||||
# R701 | Oxibadge
|
||||
|
||||
[](https://www.rust-lang.org)
|
||||
[](https://claude.com/product/claude-code)
|
||||
@@ -11,58 +11,16 @@
|
||||
|
||||
</div><br>
|
||||
|
||||
> A reverse-engineered library to communicate with the
|
||||
> [R701](https://ipsattendant.it/rilevatore-presenze-r701/) by [I.P.S.
|
||||
> Informatica](https://ipsinformatica.info/), written in Rust
|
||||
> A reverse-engineered client for the
|
||||
> [R701](https://ipsattendant.it/rilevatore-presenze-r701/) attendance reader by
|
||||
> [I.P.S. Informatica](https://ipsinformatica.info/)
|
||||
|
||||
If you want to read about this reverse engineering attempt, check out
|
||||
<https://nicolabelluti.me/series/attendance-reader/>.
|
||||
This repository is a Cargo workspace with two members:
|
||||
|
||||
## Library Usage
|
||||
- **[`r701/`](r701/README.md)** — the async Rust library that speaks the
|
||||
device's TCP protocol.
|
||||
- **`oxibadge/`** — Oxibadge, a minimal Tauri + Svelte desktop client built on
|
||||
top of the library. *(Coming soon.)*
|
||||
|
||||
1. Add the library to you project:
|
||||
|
||||
```shell
|
||||
cargo add r701 --git https://git.nicolabelluti.me/nicolabelluti/r701.git
|
||||
```
|
||||
|
||||
2. Use the library in you project:
|
||||
|
||||
This library is async and built on [tokio](https://tokio.rs); add it to your
|
||||
own `[dependencies]` (e.g. `tokio = { version = "1", features =
|
||||
["rt-multi-thread", "macros"] }`) to run the example below.
|
||||
|
||||
```rust
|
||||
use r701::R701;
|
||||
use tokio_stream::StreamExt;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let r701 = R701::connect("127.0.0.1:5005").await.unwrap();
|
||||
let mut record_stream = r701.into_record_iter().await.unwrap();
|
||||
let mut id = 0;
|
||||
|
||||
println!("No\tMchn\tEnNo\t\tName\t\tMode\tIOMd\tDateTime\t");
|
||||
while let Some(record) = record_stream.next().await {
|
||||
let record = record.unwrap();
|
||||
let name = match r701.get_name(record.employee_id).await.unwrap() {
|
||||
Some(Ok(name)) => name,
|
||||
Some(Err(error)) => String::from_utf8_lossy(error.as_bytes()).into_owned(),
|
||||
None => format!("user #{}", record.employee_id),
|
||||
};
|
||||
|
||||
println!(
|
||||
"{:0>6}\t{}\t{:0>9}\t{: <10}\t{}\t{}\t{}",
|
||||
id + 1,
|
||||
1,
|
||||
record.employee_id,
|
||||
name,
|
||||
35,
|
||||
record.clock as u8,
|
||||
record.datetime.format("%Y/%m/%d %H:%M:%S"),
|
||||
);
|
||||
|
||||
id += 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
If you want to read about the reverse engineering attempt behind the library,
|
||||
check out <https://nicolabelluti.me/series/attendance-reader/>.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
[package]
|
||||
name = "r701"
|
||||
version = "0.2.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
async-stream = "0.3.6"
|
||||
chrono = { version = "0.4.38", default-features = false, features = ["clock"] }
|
||||
serde = { version = "1.0.203", default-features = false, features = ["derive"], optional = true }
|
||||
tokio = { version = "1.53.1", default-features = false, features = ["net", "io-util", "sync"] }
|
||||
tokio-stream = { version = "0.1.19", default-features = false }
|
||||
|
||||
[features]
|
||||
serde = ["chrono/serde", "dep:serde"]
|
||||
|
||||
[lints.rust]
|
||||
unsafe_code = "forbid"
|
||||
|
||||
[lints.clippy]
|
||||
unwrap_used = "deny"
|
||||
enum_glob_use = { level = "deny", priority = 1 }
|
||||
pedantic = { level = "deny", priority = -1 }
|
||||
nursery = { level = "deny", priority = -1 }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1.53.1", features = ["rt", "macros", "net"] }
|
||||
@@ -0,0 +1,68 @@
|
||||
<div align="center">
|
||||
|
||||
# R701 🕰️
|
||||
|
||||
[](https://www.rust-lang.org)
|
||||
[](https://claude.com/product/claude-code)
|
||||
[](https://choosealicense.com/licenses/agpl-3.0)
|
||||
[](https://buymeacoffee.com/nicolabelluti)
|
||||
<br>
|
||||
[](https://git.nicolabelluti.me/nicolabelluti/r701/actions/?workflow=check-format-and-test.yaml)
|
||||
|
||||
</div><br>
|
||||
|
||||
> A reverse-engineered library to communicate with the
|
||||
> [R701](https://ipsattendant.it/rilevatore-presenze-r701/) by [I.P.S.
|
||||
> Informatica](https://ipsinformatica.info/), written in Rust
|
||||
|
||||
If you want to read about this reverse engineering attempt, check out
|
||||
<https://nicolabelluti.me/series/attendance-reader/>.
|
||||
|
||||
## Library Usage
|
||||
|
||||
1. Add the library to you project:
|
||||
|
||||
```shell
|
||||
cargo add r701 --git https://git.nicolabelluti.me/nicolabelluti/r701.git
|
||||
```
|
||||
|
||||
2. Use the library in you project:
|
||||
|
||||
This library is async and built on [tokio](https://tokio.rs); add it to your
|
||||
own `[dependencies]` (e.g. `tokio = { version = "1", features =
|
||||
["rt-multi-thread", "macros"] }`) to run the example below.
|
||||
|
||||
```rust
|
||||
use r701::R701;
|
||||
use tokio_stream::StreamExt;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let r701 = R701::connect("127.0.0.1:5005").await.unwrap();
|
||||
let mut record_stream = r701.into_record_iter().await.unwrap();
|
||||
let mut id = 0;
|
||||
|
||||
println!("No\tMchn\tEnNo\t\tName\t\tMode\tIOMd\tDateTime\t");
|
||||
while let Some(record) = record_stream.next().await {
|
||||
let record = record.unwrap();
|
||||
let name = match r701.get_name(record.employee_id).await.unwrap() {
|
||||
Some(Ok(name)) => name,
|
||||
Some(Err(error)) => String::from_utf8_lossy(error.as_bytes()).into_owned(),
|
||||
None => format!("user #{}", record.employee_id),
|
||||
};
|
||||
|
||||
println!(
|
||||
"{:0>6}\t{}\t{:0>9}\t{: <10}\t{}\t{}\t{}",
|
||||
id + 1,
|
||||
1,
|
||||
record.employee_id,
|
||||
name,
|
||||
35,
|
||||
record.clock as u8,
|
||||
record.datetime.format("%Y/%m/%d %H:%M:%S"),
|
||||
);
|
||||
|
||||
id += 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user