make listing name optional (e.g. invalid utf-8 encoding)

This commit is contained in:
yggverse 2025-07-10 14:41:37 +03:00
parent fc27f46cdf
commit 0d38aa5c06
4 changed files with 30 additions and 26 deletions

View file

@ -62,7 +62,7 @@ impl Index {
infohash: String, infohash: String,
node: u64, node: u64,
size: u64, size: u64,
list: Option<Vec<(String, u64)>>, list: Option<Vec<(Option<String>, u64)>>,
name: Option<String>, name: Option<String>,
) { ) {
if self if self

View file

@ -8,7 +8,7 @@ pub struct Value {
// Isolate by applying internal filter on value set // Isolate by applying internal filter on value set
size: Option<u64>, size: Option<u64>,
name: Option<String>, name: Option<String>,
list: Option<Vec<(String, u64)>>, list: Option<Vec<(Option<String>, u64)>>,
} }
impl Value { impl Value {
@ -17,14 +17,14 @@ impl Value {
node: u64, node: u64,
size: Option<u64>, size: Option<u64>,
name: Option<String>, name: Option<String>,
list: Option<Vec<(String, u64)>>, list: Option<Vec<(Option<String>, u64)>>,
) -> Self { ) -> Self {
Self { Self {
time: Utc::now(), time: Utc::now(),
node, node,
size, size,
list: filter_list(list), list: list.map(|f| f.into_iter().map(|(n, l)| (filter(n), l)).collect()),
name: filter_name(name), name: filter(name),
} }
} }
/// Get reference to the safely constructed `name` member /// Get reference to the safely constructed `name` member
@ -32,7 +32,7 @@ impl Value {
self.name.as_ref() self.name.as_ref()
} }
/// Get reference to the safely constructed files `list` member /// Get reference to the safely constructed files `list` member
pub fn list(&self) -> Option<&Vec<(String, u64)>> { pub fn list(&self) -> Option<&Vec<(Option<String>, u64)>> {
self.list.as_ref() self.list.as_ref()
} }
/// Get reference to the safely constructed `length` member /// Get reference to the safely constructed `length` member
@ -41,20 +41,14 @@ impl Value {
} }
} }
fn filter_name(value: Option<String>) -> Option<String> {
value.map(filter)
}
fn filter_list(value: Option<Vec<(String, u64)>>) -> Option<Vec<(String, u64)>> {
value.map(|f| f.into_iter().map(|(n, l)| (filter(n), l)).collect())
}
/// Strip tags and bom chars, crop long strings (prevents memory pool overload) /// Strip tags and bom chars, crop long strings (prevents memory pool overload)
fn filter(value: String) -> String { fn filter(value: Option<String>) -> Option<String> {
value.map(|v| {
const C: usize = 125; // + 3 for `...` offset, 128 chars max @TODO optional const C: usize = 125; // + 3 for `...` offset, 128 chars max @TODO optional
let s = value._strip_bom()._strip_tags(); let s = v._strip_bom()._strip_tags();
if s.chars().count() > C { if s.chars().count() > C {
return format!("{}...", s.chars().take(C).collect::<String>()); return format!("{}...", s.chars().take(C).collect::<String>());
} }
s s
})
} }

View file

@ -363,7 +363,10 @@ fn size(info: &TorrentMetaV1Info<ByteBufOwned>) -> u64 {
t t
} }
fn list(info: &TorrentMetaV1Info<ByteBufOwned>, limit: usize) -> Option<Vec<(String, u64)>> { fn list(
info: &TorrentMetaV1Info<ByteBufOwned>,
limit: usize,
) -> Option<Vec<(Option<String>, u64)>> {
info.files.as_ref().map(|files| { info.files.as_ref().map(|files| {
let mut b = Vec::with_capacity(files.len()); let mut b = Vec::with_capacity(files.len());
let mut i = files.iter(); let mut i = files.iter();
@ -387,7 +390,7 @@ fn list(info: &TorrentMetaV1Info<ByteBufOwned>, limit: usize) -> Option<Vec<(Str
}) })
.collect(), .collect(),
) )
.unwrap_or_default(), .ok(),
f.length, f.length,
)); ));
continue; continue;
@ -397,7 +400,7 @@ fn list(info: &TorrentMetaV1Info<ByteBufOwned>, limit: usize) -> Option<Vec<(Str
for f in i.by_ref() { for f in i.by_ref() {
l += f.length l += f.length
} }
b.push(("...".to_string(), l)); b.push((Some("...".to_string()), l));
break; break;
} }
b[..t].sort_by(|a, b| a.0.cmp(&b.0)); // @TODO optional b[..t].sort_by(|a, b| a.0.cmp(&b.0)); // @TODO optional

View file

@ -104,7 +104,10 @@ impl Rss {
} }
} }
pub fn item_description(size: Option<u64>, list: Option<&Vec<(String, u64)>>) -> Option<String> { pub fn item_description(
size: Option<u64>,
list: Option<&Vec<(Option<String>, u64)>>,
) -> Option<String> {
use crate::format::Format; use crate::format::Format;
if size.is_none() && list.is_none() { if size.is_none() && list.is_none() {
return None; return None;
@ -115,7 +118,11 @@ pub fn item_description(size: Option<u64>, list: Option<&Vec<(String, u64)>>) ->
} }
if let Some(l) = list { if let Some(l) = list {
for (path, size) in l { for (path, size) in l {
b.push(format!("{path} ({})", size.bytes())) b.push(format!(
"{} ({})",
path.as_deref().unwrap_or("?"), // @TODO invalid encoding
size.bytes()
))
} }
} }
Some(b.join("\n")) Some(b.join("\n"))