lynceus 0.4.2

lynceus is a file watcher that reports file changes using a webhook.
use serde::Serialize;
use std::path::PathBuf;
use std::time::SystemTime;

fn serialize_path_lossy<S>(path: &std::path::Path, serializer: S) -> Result<S::Ok, S::Error>
where
    S: serde::Serializer,
{
    serializer.serialize_str(&path.to_string_lossy())
}

fn serialize_system_time_rfc3339<S>(time: &SystemTime, serializer: S) -> Result<S::Ok, S::Error>
where
    S: serde::Serializer,
{
    serializer.serialize_str(&humantime::format_rfc3339(*time).to_string())
}

#[derive(Serialize, Debug, Clone)]
pub struct Event {
    #[serde(serialize_with = "serialize_system_time_rfc3339")]
    timestamp: SystemTime,

    #[serde(flatten)]
    payload: EventPayload,
}

#[derive(Serialize, Debug, Clone)]
#[serde(tag = "type")]
enum EventPayload {
    #[serde(rename = "file.created")]
    FileCreated {
        #[serde(serialize_with = "serialize_path_lossy")]
        path: PathBuf,
    },
}

impl Event {
    fn new(payload: EventPayload) -> Self {
        Self {
            timestamp: SystemTime::now(),
            payload,
        }
    }

    pub fn file_created(path: PathBuf) -> Self {
        Self::new(EventPayload::FileCreated { path })
    }

    #[cfg(test)]
    pub fn with_timestamp(mut self, timestamp: SystemTime) -> Self {
        self.timestamp = timestamp;
        self
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::path::Path;

    #[test]
    fn test_event_serialization() {
        let event = Event::file_created(Path::new("dir/file.txt").to_path_buf())
            .with_timestamp(SystemTime::UNIX_EPOCH);
        let serialized = serde_json::to_value(&event).unwrap();
        assert_eq!(serialized["type"], "file.created");
        assert_eq!(serialized["path"], "dir/file.txt");
        assert_eq!(serialized["timestamp"], "1970-01-01T00:00:00Z");
    }
}