pub mod client;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use snafu::{ResultExt, Snafu};
pub type Result<T> = std::result::Result<T, Error>;
pub const PINBOARD_API_URL: &str = "https://api.pinboard.in/v1/";
#[non_exhaustive]
#[derive(Debug, Snafu)]
#[allow(clippy::enum_variant_names)]
pub enum Error {
#[snafu(display("HTTP request error: {source}"))]
HttpError {
source: reqwest::Error,
},
JsonEncodeError {
source: serde_json::Error,
},
JsonDecodeError {
source: serde_json::Error,
},
#[snafu(display("Malformed token: {reason}"))]
MalformedTokenError {
reason: String,
},
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct BookmarkCollection {
pub last_updated: DateTime<Utc>,
pub user: String,
pub bookmarks: Vec<Bookmark>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Bookmark {
pub url: String,
pub title: String,
pub description: String,
pub tags: Vec<String>,
pub time: DateTime<Utc>,
pub shared: bool,
pub toread: bool,
pub meta: String,
pub hash: String,
}
impl BookmarkCollection {
pub fn read<R>(reader: R) -> Result<BookmarkCollection>
where
R: std::io::Read,
{
serde_json::from_reader(reader).context(JsonDecodeSnafu {})
}
pub fn write<W>(&self, writer: W) -> Result<()>
where
W: std::io::Write,
{
serde_json::to_writer(writer, self).context(JsonEncodeSnafu {})
}
pub fn from_api(client: &client::Client) -> Result<BookmarkCollection> {
let user = client.user()?;
let last_updated = client.last_update()?;
let bookmarks = client.bookmarks()?;
Ok(BookmarkCollection {
user,
bookmarks,
last_updated,
})
}
pub fn find_by_url(&self, url: &str) -> Option<&Bookmark> {
self.bookmarks.iter().find(|b| b.url == url)
}
}