diff --git a/src/index.rs b/src/index.rs index 0ac3859..b16f3ed 100644 --- a/src/index.rs +++ b/src/index.rs @@ -1,11 +1,7 @@ -use chrono::{DateTime, Utc}; -use std::collections::HashMap; +mod value; -pub struct Value { - pub time: DateTime, - pub node: u64, - pub name: Option, -} +use std::collections::HashMap; +use value::Value; /// Collect processed info hashes to skip on the next iterations (for this session) /// * also contains optional meta info to export index as RSS or any other format @@ -52,11 +48,7 @@ impl Index { .index .insert( infohash, - Value { - time: Utc::now(), - node, - name: if self.has_name { name } else { None }, - }, + Value::new(node, if self.has_name { name } else { None }), ) .is_none() { diff --git a/src/index/value.rs b/src/index/value.rs new file mode 100644 index 0000000..4198cf8 --- /dev/null +++ b/src/index/value.rs @@ -0,0 +1,37 @@ +use chrono::{DateTime, Utc}; + +const NAME_MAX_LEN: usize = 125; // + 3 bytes for `...` offset @TODO optional + +/// The `Index` value +pub struct Value { + pub time: DateTime, + pub node: u64, + /// Isolate by applying internal filter on value set + name: Option, +} + +impl Value { + /// Create new `Self` with current timestamp + pub fn new(node: u64, name: Option) -> Self { + Self { + time: Utc::now(), + node, + name: filter_name(name), + } + } + /// Get reference to the safely constructed `name` member + pub fn name(&self) -> Option<&String> { + self.name.as_ref() + } +} + +/// Prevent unexpected memory usage on store values from unknown source +fn filter_name(value: Option) -> Option { + value.map(|v| { + if v.len() > NAME_MAX_LEN { + format!("{}...", &v[..NAME_MAX_LEN]) + } else { + v + } + }) +} diff --git a/src/main.rs b/src/main.rs index 49202b2..4e840a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -198,7 +198,7 @@ async fn main() -> Result<()> { for (k, v) in index.list() { rss.push( k, - v.name.as_ref().unwrap_or(k), + v.name().unwrap_or(k), None, // @TODO Some(&v.time.to_rfc2822()), )?