use crate::Error;
use crate::Result;
use crate::utils::UtcTime;
use async_trait::async_trait;
use chrono::DateTime;
use chrono::Utc;
use derive_more::Display;
use serde::Deserialize;
use serde::Serialize;
use std::{fs, path::PathBuf};
pub trait UrlStore {
fn add(&mut self, entry: AnnotatedUrl) -> Result<()>;
fn remove(&mut self, query: &str) -> Result<Vec<AnnotatedUrl>>;
fn filter(&self, query: Option<&str>) -> Vec<AnnotatedUrl>;
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct AnnotatedUrl {
pub url: String,
pub description: Option<String>,
pub created: Option<UtcTime>,
}
impl AnnotatedUrl {
pub fn new(url: String, description: Option<String>) -> Self {
Self {
url,
description,
created: Some(Utc::now()),
}
}
}
impl Display for AnnotatedUrl {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.url)?;
if let Some(d) = &self.description {
write!(f, " ({d})")?;
}
Ok(())
}
}
#[derive(Debug, Display)]
pub enum UrlError {
#[display("'{_0}' is already in the URL store")]
AlreadyInStore(String),
#[display("'{_0}' was not found in the URL store")]
NotFound(String),
}
impl From<UrlError> for Error {
fn from(e: UrlError) -> Error {
Error::Custom(e.to_string())
}
}