idk if th is is good ima jus commit anyways

This commit is contained in:
lda
2025-12-07 00:13:42 +07:00 Unverified
parent afffcd5528
commit 00cf33eefb
17 changed files with 58 additions and 125 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
{
"rust-analyzer.cargo.target": "armv7-unknown-linux-musleabihf",
"rust-analyzer.diagnostics.disabled": ["unlinked-file"]
// "rust-analyzer.diagnostics.disabled": ["unlinked-file"]
}
+1 -1
View File
@@ -65,7 +65,7 @@ pub enum NUDState {
/// failed.
Failed,
Other(u16)
Other(u16),
}
/// everything i see
+1 -1
View File
@@ -1,2 +1,2 @@
pub mod mac;
pub mod vec;
// pub mod vec;
+1 -1
View File
@@ -8,7 +8,7 @@ enum OneOrMany<T> {
Many(Vec<T>),
}
pub fn vec_from_strs<'de, D, T>(des: D) -> Result<Vec<T>, D::Error>
pub fn deserialize<'de, D, T>(des: D) -> Result<Vec<T>, D::Error>
where
D: serde::Deserializer<'de>,
T: std::str::FromStr,
+2 -2
View File
@@ -10,7 +10,7 @@
use std::{net::IpAddr, str::FromStr};
use crate::utils::parse::mac::ser_opm;
use crate::utils::parse::mac;
use macaddr::MacAddr;
use serde_with::skip_serializing_none;
use strum::{Display, EnumString};
@@ -33,7 +33,7 @@ pub struct IpNeighLine {
pub ip: IpAddr,
pub dev: Option<String>,
/// link layer address
#[serde(serialize_with = "ser_opm")]
#[serde(with = "mac::option_mac")]
pub mac: Option<MacAddr>,
/// Neighbour Unreachability Detection
pub state: NUDState,
+2 -6
View File
@@ -42,8 +42,8 @@ pub async fn read_dhcp_leases_with_names() -> io::Result<Vec<DhcpLeaseLine>> {
}
Ok(leases_with_names)
}
use crate::utils::parse::mac;
use macaddr::MacAddr;
use serde::Serializer;
use std::io::{self, ErrorKind};
use std::net::IpAddr;
@@ -53,15 +53,11 @@ pub struct DhcpLeaseLine {
/// Epoch seconds when the lease expires
pub expires_epoch: u64,
pub ip: IpAddr,
#[serde(serialize_with = "ser_mac")]
#[serde(with = "mac")]
pub mac: MacAddr,
pub name: Option<String>,
}
fn ser_mac<S: Serializer>(m: &MacAddr, s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(&m.to_string())
}
/// Parse one line of /tmp/dhcp.leases
pub fn parse_dhcp_lease_line(line: &str) -> Option<DhcpLeaseLine> {
let mut c = line.split_whitespace();
+1 -1
View File
@@ -13,7 +13,7 @@ pub async fn status_smart_redirect(
Path(q): Path<String>,
) -> axum::response::Result<Redirect, impl IntoResponse> {
// no less bullshit
let query = match parse_query(q) {
let query = match parse_query(q).await {
QueryType::Ip(ip_addr) => DeviceQuery {
filter: Filters {
ips: vec![ip_addr],
+1 -1
View File
@@ -2,6 +2,6 @@ use crate::utils::query::dev;
use axum::Json;
pub async fn devs_router() -> Json<Vec<String>> {
dev::devs_sorted().into()
dev::devs_sorted().await.into()
}
// Device listing endpoints
+1 -1
View File
@@ -13,7 +13,7 @@ pub struct ApiError {
}
impl ApiError {
/// [StatusCode::INTERNAL_SERVER_ERROR]
/// [StatusCode::INTERNAL_SERVER_ERROR] shortcut
pub const fn ise(error: String) -> Self {
Self {
code: StatusCode::INTERNAL_SERVER_ERROR,
+10 -10
View File
@@ -4,11 +4,10 @@ use axum_extra::extract::Query;
use macaddr::MacAddr;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use serde_with::{DisplayFromStr, OneOrMany, serde_as};
use std::net::IpAddr;
use crate::arpparse::NUDState;
use crate::utils::parse::de_many;
use crate::utils::parse::serialize_macs;
use crate::utils::query::get_macs;
#[derive(Debug, Default, Clone, Hash, Deserialize, Serialize)]
@@ -31,19 +30,20 @@ pub struct Status<T> {
pub filters: Filters,
}
#[serde_as]
#[derive(Debug, Default, Clone, Hash, Serialize, Deserialize)]
pub struct Filters {
#[serde(default, deserialize_with = "de_many::vec_from_strs")]
#[serde_as(as = "OneOrMany<_>")]
#[serde(default)]
pub ips: Vec<IpAddr>,
#[serde(default, deserialize_with = "de_many::vec_from_strs")]
#[serde_as(as = "OneOrMany<_>")]
#[serde(default)]
pub devs: Vec<String>,
#[serde(default, deserialize_with = "de_many::vec_from_strs")]
#[serde_as(as = "OneOrMany<_>")]
#[serde(default)]
pub nuds: Vec<NUDState>,
#[serde(
default,
deserialize_with = "de_many::vec_from_strs",
serialize_with = "serialize_macs"
)]
#[serde_as(as = "OneOrMany<DisplayFromStr>")]
#[serde(default)]
pub macs: Vec<MacAddr>,
}
+2 -2
View File
@@ -4,7 +4,7 @@ use std::net::IpAddr;
/* use crate::arpparse::IpNeighLine;
use crate::route::api::Status; */
use crate::utils::parse::mac::{des_opm, ser_opm};
use crate::utils::parse::mac;
use crate::utils::wake::wake_one;
use axum::{extract::Json, http::StatusCode, response::IntoResponse};
use futures::TryFutureExt;
@@ -44,7 +44,7 @@ pub enum WakeTargetStatus {
pub struct WakeTarget {
#[serde(default)]
pub ip: Option<IpAddr>,
#[serde(default, serialize_with = "ser_opm", deserialize_with = "des_opm")]
#[serde(default, with = "mac::option_mac")]
pub mac: Option<MacAddr>,
}
+19 -58
View File
@@ -100,52 +100,12 @@ pub fn boolish_str(s: &str) -> bool {
&& t.parse::<u64>().map(|n| n != 0).unwrap_or(false))
}
pub mod de_many {
use serde::Deserialize;
use serde::de;
#[derive(Deserialize)]
#[serde(untagged)]
enum OneOrMany<T> {
One(T),
Many(Vec<T>),
}
pub fn vec_from_strs<'de, D, T>(des: D) -> Result<Vec<T>, D::Error>
where
D: serde::Deserializer<'de>,
T: std::str::FromStr,
T::Err: std::fmt::Display,
{
let raw: OneOrMany<String> = OneOrMany::<String>::deserialize(des)?;
let mut out = Vec::new();
match raw {
OneOrMany::One(s) => {
let t = s.trim();
if !t.is_empty() {
out.push(t.parse().map_err(de::Error::custom)?);
}
}
OneOrMany::Many(vs) => {
for s in vs {
let t = s.trim();
if t.is_empty() {
continue;
}
out.push(t.parse().map_err(de::Error::custom)?);
}
}
}
Ok(out)
}
}
pub mod mac {
use macaddr::MacAddr;
use serde::{self, Deserialize, Deserializer, de::Error as DeError};
use serde::{Serialize, Serializer, de};
pub fn serialize_macs<S>(macs: &[MacAddr], serializer: S) -> Result<S::Ok, S::Error>
pub fn _serialize_macs<S>(macs: &[MacAddr], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
@@ -154,7 +114,7 @@ pub mod mac {
}
/// Serialize a MacAddr as a string
pub fn _serialize_mac<S>(mac: &MacAddr, serializer: S) -> Result<S::Ok, S::Error>
pub fn serialize<S>(mac: &MacAddr, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
@@ -162,7 +122,7 @@ pub mod mac {
}
/// Deserialize a MacAddr from a string
pub fn _deserialize_mac<'de, D>(deserializer: D) -> Result<MacAddr, D::Error>
pub fn _deserialize<'de, D>(deserializer: D) -> Result<MacAddr, D::Error>
where
D: Deserializer<'de>,
{
@@ -170,21 +130,22 @@ pub mod mac {
s.parse::<MacAddr>().map_err(DeError::custom)
}
/// serialize an [`Option<MacAddr>`]
pub fn ser_opm<S: Serializer>(bro: &Option<MacAddr>, ser: S) -> Result<S::Ok, S::Error> {
Option::<String>::serialize(&bro.as_ref().map(ToString::to_string), ser)
}
pub mod option_mac {
use super::*;
/// serialize an [`Option<MacAddr>`]
pub fn serialize<S: Serializer>(bro: &Option<MacAddr>, ser: S) -> Result<S::Ok, S::Error> {
Option::<String>::serialize(&bro.as_ref().map(ToString::to_string), ser)
}
/// deserialize an [`Option<MacAddr>`]
pub fn des_opm<'de, D>(des: D) -> Result<Option<MacAddr>, D::Error>
where
D: serde::Deserializer<'de>,
{
Option::<&str>::deserialize(des)?
.map(str::parse)
.transpose()
.map_err(de::Error::custom)
/// deserialize an [`Option<MacAddr>`]
pub fn deserialize<'de, D>(des: D) -> Result<Option<MacAddr>, D::Error>
where
D: serde::Deserializer<'de>,
{
Option::<&str>::deserialize(des)?
.map(str::parse)
.transpose()
.map_err(de::Error::custom)
}
}
}
pub use mac::*;
+11 -32
View File
@@ -1,45 +1,24 @@
use std::{collections::HashSet, fs};
use lda_ipjs::subcommands::address::json as ipjs_json;
use std::collections::HashSet;
pub fn get_dev() -> HashSet<String> {
pub async fn get_dev() -> HashSet<String> {
let mut devs: HashSet<String> = HashSet::new();
if let Ok(rd) = std::fs::read_dir("/sys/class/net") {
for e in rd.flatten() {
if e.file_type()
.map(|ft| {
if ft.is_symlink() {
// true
fs::metadata(e.path()).map(|m| m.is_dir()).unwrap_or(false)
} else {
ft.is_dir()
}
})
.unwrap_or(false)
&& let Ok(name) = e.file_name().into_string()
&& name != "lo"
&& !name.is_empty()
{
devs.insert(name);
}
}
} else if let Ok(txt) = std::fs::read_to_string("/proc/net/dev") {
for line in txt.lines().skip(2) {
if let Some((name, _rest)) = line.split_once(':') {
let n = name.trim().to_string();
if n != "lo" && !n.is_empty() {
devs.insert(n);
}
if let Ok(items) = ipjs_json::get(None).await {
for item in items {
if item.ifname != "lo" && !item.ifname.is_empty() {
devs.insert(item.ifname);
}
}
}
devs
}
pub fn devs_sorted() -> Vec<String> {
let mut v: Vec<String> = get_dev().into_iter().collect();
pub async fn devs_sorted() -> Vec<String> {
let mut v: Vec<String> = get_dev().await.into_iter().collect();
v.sort();
v
}
pub fn has_dev(name: &str) -> bool {
get_dev().contains(name)
pub async fn has_dev(name: &str) -> bool {
get_dev().await.contains(name)
}
-5
View File
@@ -13,11 +13,6 @@ pub async fn get_ips(machine_name: &str) -> Result<impl Iterator<Item = IpAddr>>
.map(|c| c.ip()))
}
// #[deprecated(
// since = "0.1.5",
// note = "just call once everything with get mac
// and then filter it bro WHY DO YOU EVEN DO TS"
// )]
// good now
//
// Current logic: When filtering by exactly 1 dev/mac, exclude entries missing that field.
+2 -2
View File
@@ -12,7 +12,7 @@ pub enum QueryType {
Unknown(String),
}
pub fn parse_query(q: String) -> QueryType {
pub async fn parse_query(q: String) -> QueryType {
let s = if cfg!(feature = "very-smart-parsing") {
crate::utils::parse::extract_host(&q)
} else {
@@ -36,7 +36,7 @@ pub fn parse_query(q: String) -> QueryType {
return QueryType::Nud(state);
}
// 4) Known device? prefer dev first
if has_dev(s) {
if has_dev(s).await {
return QueryType::Dev(s.to_string());
}
// Default: name last // it will fail also
+2
View File
@@ -1,3 +1,5 @@
//! why did my Head Ass split these into two.
pub mod impls;
use std::{io, net::IpAddr};