use std::sync::Arc;
use ldk_node::payment::PaymentDirection;
use serde::Deserialize;
use crate::CdkLdkNode;
#[derive(Clone)]
pub struct AppState {
pub node: Arc<CdkLdkNode>,
}
pub fn deserialize_optional_u32<'de, D>(deserializer: D) -> Result<Option<u32>, D::Error>
where
D: serde::Deserializer<'de>,
{
let opt = Option::<String>::deserialize(deserializer)?;
match opt.as_deref() {
None | Some("") => Ok(None),
Some(s) => s.parse::<u32>().map(Some).map_err(serde::de::Error::custom),
}
}
pub fn deserialize_optional_u64<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
where
D: serde::Deserializer<'de>,
{
let opt = Option::<String>::deserialize(deserializer)?;
match opt.as_deref() {
None | Some("") => Ok(None),
Some(s) => s.parse::<u64>().map(Some).map_err(serde::de::Error::custom),
}
}
pub fn deserialize_optional_f64<'de, D>(deserializer: D) -> Result<Option<f64>, D::Error>
where
D: serde::Deserializer<'de>,
{
let opt = Option::<String>::deserialize(deserializer)?;
match opt.as_deref() {
None | Some("") => Ok(None),
Some(s) => s.parse::<f64>().map(Some).map_err(serde::de::Error::custom),
}
}
pub fn get_paginated_payments_streaming(
node: &ldk_node::Node,
filter: &str,
skip: usize,
take: usize,
) -> (Vec<ldk_node::payment::PaymentDetails>, usize) {
let filter_fn = match filter {
"incoming" => {
|p: &&ldk_node::payment::PaymentDetails| p.direction == PaymentDirection::Inbound
}
"outgoing" => {
|p: &&ldk_node::payment::PaymentDetails| p.direction == PaymentDirection::Outbound
}
_ => |_: &&ldk_node::payment::PaymentDetails| true,
};
let filtered_payments = node.list_payments_with_filter(filter_fn);
let mut time_indexed: Vec<_> = filtered_payments
.iter()
.enumerate()
.map(|(idx, payment)| (payment.latest_update_timestamp, idx))
.collect();
time_indexed.sort_unstable_by_key(|b| std::cmp::Reverse(b.0));
let total_count = time_indexed.len();
let page_payments: Vec<_> = time_indexed
.into_iter()
.skip(skip)
.take(take)
.map(|(_, idx)| filtered_payments[idx].clone())
.collect();
(page_payments, total_count)
}