use rand::Rng;
use serde_derive::{Deserialize, Serialize};
use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::convert::TryInto;
use std::ops::Deref;
use std::sync::Arc;
use trout::hyper::RoutingFailureExtHyper;
mod apub_util;
mod routes;
mod tasks;
mod worker;
#[derive(Clone, Serialize, Deserialize)]
#[serde(try_from = "url::Url")]
#[serde(into = "url::Url")]
pub struct BaseURL(url::Url);
impl BaseURL {
pub fn path_segments_mut(&mut self) -> url::PathSegmentsMut {
self.0.path_segments_mut().unwrap()
}
pub fn set_fragment(&mut self, fragment: Option<&str>) {
self.0.set_fragment(fragment);
}
}
impl std::ops::Deref for BaseURL {
type Target = url::Url;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl std::fmt::Display for BaseURL {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Display::fmt(&self.0, f)
}
}
#[derive(Debug)]
pub struct CannotBeABase;
impl std::fmt::Display for CannotBeABase {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "That URL cannot be a base")
}
}
impl std::convert::TryFrom<url::Url> for BaseURL {
type Error = CannotBeABase;
fn try_from(src: url::Url) -> Result<BaseURL, Self::Error> {
if src.cannot_be_a_base() {
Err(CannotBeABase)
} else {
Ok(BaseURL(src))
}
}
}
impl std::str::FromStr for BaseURL {
type Err = crate::Error;
fn from_str(src: &str) -> Result<Self, Self::Err> {
let url: url::Url = src.parse()?;
url.try_into()
.map_err(|_| crate::Error::InternalStrStatic("Parsed URL cannot be a base"))
}
}
impl From<BaseURL> for url::Url {
fn from(src: BaseURL) -> url::Url {
src.0
}
}
impl Into<activitystreams::base::AnyBase> for BaseURL {
fn into(self) -> activitystreams::base::AnyBase {
self.0.into()
}
}
impl Into<activitystreams::primitives::OneOrMany<activitystreams::base::AnyBase>> for BaseURL {
fn into(self) -> activitystreams::primitives::OneOrMany<activitystreams::base::AnyBase> {
self.0.into()
}
}
#[derive(Serialize, Default)]
pub struct Empty {}
pub struct Pineapple {
value: i32,
}
impl Pineapple {
pub fn generate() -> Self {
Self {
value: rand::thread_rng().gen(),
}
}
pub fn as_int(&self) -> i32 {
self.value
}
}
// implementing this trait is discouraged in favor of Display, but bs58 doesn't do streaming output
impl std::string::ToString for Pineapple {
fn to_string(&self) -> String {
bs58::encode(&self.value.to_be_bytes()).into_string()
}
}
impl std::str::FromStr for Pineapple {
type Err = bs58::decode::Error;
fn from_str(src: &str) -> Result<Self, Self::Err> {
let src = s