From 1dcddc23dead8a0a692cbbab1dc89814ba9176e7 Mon Sep 17 00:00:00 2001 From: Daniel Sockwell Date: Tue, 21 Apr 2020 16:39:31 -0400 Subject: [PATCH] Update module privacy (#133) This squashed commit rolls up a series of changes designed to improve Flodgatt's public API/module boundary. Specifically, this limits the number of Items that are exported outside the top-level modules (in some cases because they were already not needed outside that module due to the earlier code reorganization and in some cases by using public re-exports to export particular Items from a private module). Similarly, this commit moves the `Event` struct to the `response` module (maintaining privacy for the `Event`'s implementation details) while re-exporting the `Id` struct that `Event` uses internally at the top level. All of these changes are made with the goal of making Flodgatt's code easier to reason about in isolation, which should both make it easier to maintain and make it easier for new contributors to make changes without understanding the entire codebase. Additionally, having fewer public modules will make documenting Flodgatt more extensively much easier. --- src/config.rs | 5 +++- src/config/deployment_cfg.rs | 10 ++----- src/config/deployment_cfg_types.rs | 23 ++------------- src/config/environmental_variables.rs | 13 +++++---- src/config/postgres_cfg.rs | 14 ++++----- src/config/redis_cfg.rs | 14 ++++----- src/event.rs | 14 ++++----- src/event/checked_event.rs | 10 +++---- src/event/checked_event/status.rs | 18 ++++++++---- src/event/dynamic_event.rs | 33 +++++++++++---------- src/request.rs | 12 ++++---- src/request/err.rs | 2 -- src/request/postgres.rs | 17 +++++------ src/request/query.rs | 41 +++++++++++---------------- src/request/subscription.rs | 14 ++++----- src/request/timeline.rs | 18 ++++++++---- src/request/timeline/inner.rs | 16 +++++------ src/response.rs | 2 +- src/response/redis.rs | 15 +++++----- src/response/redis/connection.rs | 23 ++++----------- src/response/redis/connection/err.rs | 2 +- src/response/redis/manager.rs | 4 +-- src/response/redis/msg.rs | 22 ++++++-------- 23 files changed, 158 insertions(+), 184 deletions(-) diff --git a/src/config.rs b/src/config.rs index 5ade175..f7c3089 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,7 @@ -pub use {deployment_cfg::Deployment, postgres_cfg::Postgres, redis_cfg::Redis}; +pub(crate) use postgres_cfg::Postgres; +pub(crate) use redis_cfg::Redis; + +use deployment_cfg::Deployment; use self::environmental_variables::EnvVar; use super::err::FatalErr; diff --git a/src/config/deployment_cfg.rs b/src/config/deployment_cfg.rs index 90b64a2..379691e 100644 --- a/src/config/deployment_cfg.rs +++ b/src/config/deployment_cfg.rs @@ -3,27 +3,23 @@ use crate::err::FatalErr; #[derive(Debug, Default)] pub struct Deployment<'a> { - pub env: Env, - pub log_level: LogLevel, + pub(crate) env: Env, + pub(crate) log_level: LogLevel, pub address: FlodgattAddr, pub port: Port, pub unix_socket: Socket, pub cors: Cors<'a>, - pub sse_interval: SseInterval, - pub ws_interval: WsInterval, pub whitelist_mode: WhitelistMode, } impl Deployment<'_> { - pub fn from_env(env: &EnvVar) -> Result { + pub(crate) fn from_env(env: &EnvVar) -> Result { let mut cfg = Self { env: Env::default().maybe_update(env.get("NODE_ENV"))?, log_level: LogLevel::default().maybe_update(env.get("RUST_LOG"))?, address: FlodgattAddr::default().maybe_update(env.get("BIND"))?, port: Port::default().maybe_update(env.get("PORT"))?, unix_socket: Socket::default().maybe_update(env.get("SOCKET"))?, - sse_interval: SseInterval::default().maybe_update(env.get("SSE_FREQ"))?, - ws_interval: WsInterval::default().maybe_update(env.get("WS_FREQ"))?, whitelist_mode: WhitelistMode::default().maybe_update(env.get("WHITELIST_MODE"))?, cors: Cors::default(), }; diff --git a/src/config/deployment_cfg_types.rs b/src/config/deployment_cfg_types.rs index d0ac979..584a64c 100644 --- a/src/config/deployment_cfg_types.rs +++ b/src/config/deployment_cfg_types.rs @@ -1,10 +1,7 @@ use crate::from_env_var; -use std::{ - fmt, - net::{IpAddr, Ipv4Addr}, - str::FromStr, - time::Duration, -}; +use std::fmt; +use std::net::{IpAddr, Ipv4Addr}; +use std::str::FromStr; use strum_macros::{EnumString, EnumVariantNames}; from_env_var!( @@ -38,20 +35,6 @@ from_env_var!( let (env_var, allowed_values) = ("SOCKET", "any string"); let from_str = |s| Some(Some(s.to_string())); ); -from_env_var!( - /// The time between replies sent via WebSocket - let name = WsInterval; - let default: Duration = Duration::from_millis(100); - let (env_var, allowed_values) = ("WS_FREQ", "a number of milliseconds"); - let from_str = |s| s.parse().map(Duration::from_millis).ok(); -); -from_env_var!( - /// The time between replies sent via Server Sent Events - let name = SseInterval; - let default: Duration = Duration::from_millis(100); - let (env_var, allowed_values) = ("WS_FREQ", "a number of milliseconds"); - let from_str = |s| s.parse().map(Duration::from_millis).ok(); -); from_env_var!( /// The port to run Flodgatt on let name = Port; diff --git a/src/config/environmental_variables.rs b/src/config/environmental_variables.rs index 286e3a5..a1e08cf 100644 --- a/src/config/environmental_variables.rs +++ b/src/config/environmental_variables.rs @@ -2,7 +2,7 @@ use hashbrown::HashMap; use std::fmt; #[derive(Debug)] -pub struct EnvVar(pub HashMap); +pub(crate) struct EnvVar(pub HashMap); impl std::ops::Deref for EnvVar { type Target = HashMap; fn deref(&self) -> &HashMap { @@ -16,11 +16,11 @@ impl Clone for EnvVar { } } impl EnvVar { - pub fn new(vars: HashMap) -> Self { + pub(crate) fn new(vars: HashMap) -> Self { Self(vars) } - pub fn maybe_add_env_var(&mut self, key: &str, maybe_value: Option) { + pub(crate) fn maybe_add_env_var(&mut self, key: &str, maybe_value: Option) { if let Some(value) = maybe_value { self.0.insert(key.to_string(), value.to_string()); } @@ -63,7 +63,7 @@ impl fmt::Display for EnvVar { #[macro_export] macro_rules! maybe_update { ($name:ident; $item: tt:$type:ty) => ( - pub fn $name(self, item: Option<$type>) -> Self { + pub(crate) fn $name(self, item: Option<$type>) -> Self { match item { Some($item) => Self{ $item, ..self }, None => Self { ..self } @@ -106,7 +106,10 @@ macro_rules! from_env_var { fn inner_from_str($arg: &str) -> Option<$type> { $body } - pub fn maybe_update(self, var: Option<&String>) -> Result { + pub(crate) fn maybe_update( + self, + var: Option<&String>, + ) -> Result { Ok(match var { Some(empty_string) if empty_string.is_empty() => Self::default(), Some(value) => Self(Self::inner_from_str(value).ok_or_else(|| { diff --git a/src/config/postgres_cfg.rs b/src/config/postgres_cfg.rs index 63f3443..2e62ff2 100644 --- a/src/config/postgres_cfg.rs +++ b/src/config/postgres_cfg.rs @@ -8,12 +8,12 @@ type Result = std::result::Result; #[derive(Debug, Clone)] pub struct Postgres { - pub user: PgUser, - pub host: PgHost, - pub password: PgPass, - pub database: PgDatabase, - pub port: PgPort, - pub ssl_mode: PgSslMode, + pub(crate) user: PgUser, + pub(crate) host: PgHost, + pub(crate) password: PgPass, + pub(crate) database: PgDatabase, + pub(crate) port: PgPort, + pub(crate) ssl_mode: PgSslMode, } impl EnvVar { @@ -51,7 +51,7 @@ impl EnvVar { impl Postgres { /// Configure Postgres and return a connection - pub fn from_env(env: EnvVar) -> Result { + pub(crate) fn from_env(env: EnvVar) -> Result { let env = match env.get("DATABASE_URL").cloned() { Some(url_str) => env.update_with_postgres_url(&url_str)?, None => env, diff --git a/src/config/redis_cfg.rs b/src/config/redis_cfg.rs index 694678f..5f85362 100644 --- a/src/config/redis_cfg.rs +++ b/src/config/redis_cfg.rs @@ -8,12 +8,12 @@ type Result = std::result::Result; #[derive(Debug, Default)] pub struct Redis { - pub user: RedisUser, - pub password: RedisPass, - pub port: RedisPort, - pub host: RedisHost, - pub db: RedisDb, - pub namespace: RedisNamespace, + pub(crate) user: RedisUser, + pub(crate) password: RedisPass, + pub(crate) port: RedisPort, + pub(crate) host: RedisHost, + pub(crate) db: RedisDb, + pub(crate) namespace: RedisNamespace, // **NOTE**: Polling Redis is much more time consuming than polling the `Receiver` (~1ms // compared to ~50μs). Thus, changing this setting with REDIS_POLL_INTERVAL may be a good // place to start for performance improvements at the cost of delaying all updates. @@ -50,7 +50,7 @@ impl Redis { const DB_SET_WARNING: &'static str = r"Redis database specified, but PubSub connections do not use databases. For similar functionality, you may wish to set a REDIS_NAMESPACE"; - pub fn from_env(env: EnvVar) -> Result { + pub(crate) fn from_env(env: EnvVar) -> Result { let env = match env.get("REDIS_URL").cloned() { Some(url_str) => env.update_with_redis_url(&url_str)?, None => env, diff --git a/src/event.rs b/src/event.rs index 8b37d0a..a721370 100644 --- a/src/event.rs +++ b/src/event.rs @@ -2,9 +2,9 @@ mod checked_event; mod dynamic_event; mod err; -pub use checked_event::{CheckedEvent, Id}; -pub use dynamic_event::{DynEvent, DynStatus, EventKind}; -pub use err::EventErr; +pub(crate) use checked_event::{CheckedEvent, Id}; +pub(crate) use dynamic_event::{DynEvent, EventKind}; +pub(crate) use err::EventErr; use serde::Serialize; use std::convert::TryFrom; @@ -19,7 +19,7 @@ pub enum Event { } impl Event { - pub fn to_json_string(&self) -> String { + pub(crate) fn to_json_string(&self) -> String { if let Event::Ping = self { "{}".to_string() } else { @@ -32,7 +32,7 @@ impl Event { } } - pub fn to_warp_reply(&self) -> Option<(impl ServerSentEvent, impl ServerSentEvent)> { + pub(crate) fn to_warp_reply(&self) -> Option<(impl ServerSentEvent, impl ServerSentEvent)> { if let Event::Ping = self { None } else { @@ -103,8 +103,8 @@ impl TryFrom<&str> for Event { Forwarding Redis payload without type checking it.", e ); - - Ok(Event::Dynamic(serde_json::from_str(&event_txt)?)) + let dyn_event: DynEvent = serde_json::from_str(&event_txt)?; + Ok(Event::Dynamic(dyn_event.set_update()?)) } } } diff --git a/src/event/checked_event.rs b/src/event/checked_event.rs index 137d018..5104de9 100644 --- a/src/event/checked_event.rs +++ b/src/event/checked_event.rs @@ -11,12 +11,12 @@ mod status; mod tag; mod visibility; -pub use announcement::Announcement; +use announcement::Announcement; pub(in crate::event) use announcement_reaction::AnnouncementReaction; -pub use conversation::Conversation; -pub use id::Id; -pub use notification::Notification; -pub use status::Status; +use conversation::Conversation; +pub(crate) use id::Id; +use notification::Notification; +use status::Status; use serde::Deserialize; diff --git a/src/event/checked_event/status.rs b/src/event/checked_event/status.rs index 9618620..0976106 100644 --- a/src/event/checked_event/status.rs +++ b/src/event/checked_event/status.rs @@ -3,10 +3,16 @@ mod attachment; mod card; mod poll; -use super::{ - account::Account, emoji::Emoji, id::Id, mention::Mention, tag::Tag, visibility::Visibility, -}; -use {application::Application, attachment::Attachment, card::Card, poll::Poll}; +use super::account::Account; +use super::emoji::Emoji; +use super::id::Id; +use super::mention::Mention; +use super::tag::Tag; +use super::visibility::Visibility; +use application::Application; +use attachment::Attachment; +use card::Card; +use poll::Poll; use crate::request::Blocks; @@ -53,7 +59,7 @@ pub struct Status { impl Status { /// Returns `true` if the status is filtered out based on its language - pub fn language_not(&self, allowed_langs: &HashSet) -> bool { + pub(crate) fn language_not(&self, allowed_langs: &HashSet) -> bool { const ALLOW: bool = false; const REJECT: bool = true; @@ -84,7 +90,7 @@ impl Status { /// * Wrote this toot /// * Wrote a toot that this toot is replying to (if any) /// * Wrote the toot that this toot is boosting (if any) - pub fn involves_any(&self, blocks: &Blocks) -> bool { + pub(crate) fn involves_any(&self, blocks: &Blocks) -> bool { const ALLOW: bool = false; const REJECT: bool = true; let Blocks { diff --git a/src/event/dynamic_event.rs b/src/event/dynamic_event.rs index cdd0110..0ac80f2 100644 --- a/src/event/dynamic_event.rs +++ b/src/event/dynamic_event.rs @@ -10,14 +10,14 @@ use serde_json::Value; #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub struct DynEvent { #[serde(skip)] - pub kind: EventKind, - pub event: String, - pub payload: Value, - pub queued_at: Option, + pub(crate) kind: EventKind, + pub(crate) event: String, + pub(crate) payload: Value, + pub(crate) queued_at: Option, } #[derive(Debug, Clone, PartialEq)] -pub enum EventKind { +pub(crate) enum EventKind { Update(DynStatus), NonUpdate, } @@ -29,19 +29,19 @@ impl Default for EventKind { } #[derive(Debug, Clone, PartialEq)] -pub struct DynStatus { - pub id: Id, - pub username: String, - pub language: Option, - pub mentioned_users: HashSet, - pub replied_to_user: Option, - pub boosted_user: Option, +pub(crate) struct DynStatus { + pub(crate) id: Id, + pub(crate) username: String, + pub(crate) language: Option, + pub(crate) mentioned_users: HashSet, + pub(crate) replied_to_user: Option, + pub(crate) boosted_user: Option, } type Result = std::result::Result; impl DynEvent { - pub fn set_update(self) -> Result { + pub(crate) fn set_update(self) -> Result { if self.event == "update" { let kind = EventKind::Update(DynStatus::new(&self.payload.clone())?); Ok(Self { kind, ..self }) @@ -52,7 +52,7 @@ impl DynEvent { } impl DynStatus { - pub fn new(payload: &Value) -> Result { + pub(crate) fn new(payload: &Value) -> Result { use EventErr::*; Ok(Self { @@ -68,7 +68,7 @@ impl DynStatus { }) } /// Returns `true` if the status is filtered out based on its language - pub fn language_not(&self, allowed_langs: &HashSet) -> bool { + pub(crate) fn language_not(&self, allowed_langs: &HashSet) -> bool { const ALLOW: bool = false; const REJECT: bool = true; @@ -93,7 +93,7 @@ impl DynStatus { /// * Wrote this toot /// * Wrote a toot that this toot is replying to (if any) /// * Wrote the toot that this toot is boosting (if any) - pub fn involves_any(&self, blocks: &Blocks) -> bool { + pub(crate) fn involves_any(&self, blocks: &Blocks) -> bool { const ALLOW: bool = false; const REJECT: bool = true; let Blocks { @@ -112,7 +112,6 @@ impl DynStatus { } } - // involved_users = mentioned_users + author + replied-to user + boosted user fn involves(&self, blocked_users: &HashSet) -> bool { // mentions let mut involved_users: HashSet = self.mentioned_users.clone(); diff --git a/src/request.rs b/src/request.rs index 4b5a0f1..e265d77 100644 --- a/src/request.rs +++ b/src/request.rs @@ -6,11 +6,13 @@ pub mod timeline; mod err; mod subscription; -pub use self::err::RequestErr; -pub use self::postgres::PgPool; -// TODO consider whether we can remove `Stream` from public API -pub use subscription::{Blocks, Subscription}; -pub use timeline::{Content, Reach, Stream, Timeline, TimelineErr}; +pub(crate) use self::err::RequestErr; +pub(crate) use self::postgres::PgPool; + +pub(crate) use subscription::Blocks; +pub use subscription::Subscription; +pub use timeline::Timeline; +pub(crate) use timeline::{Content, Reach, Stream, TimelineErr}; use self::query::Query; use crate::config; diff --git a/src/request/err.rs b/src/request/err.rs index becc627..0637e30 100644 --- a/src/request/err.rs +++ b/src/request/err.rs @@ -1,7 +1,6 @@ use std::fmt; #[derive(Debug)] pub enum RequestErr { - Unknown, PgPool(r2d2::Error), Pg(postgres::Error), } @@ -12,7 +11,6 @@ impl fmt::Display for RequestErr { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { use RequestErr::*; let msg = match self { - Unknown => "Encountered an unrecoverable error related to handling a request".into(), PgPool(e) => format!("{}", e), Pg(e) => format!("{}", e), }; diff --git a/src/request/postgres.rs b/src/request/postgres.rs index 16ac785..a5ea50c 100644 --- a/src/request/postgres.rs +++ b/src/request/postgres.rs @@ -11,7 +11,7 @@ use std::convert::TryFrom; #[derive(Clone, Debug)] pub struct PgPool { - pub conn: r2d2::Pool>, + conn: r2d2::Pool>, whitelist_mode: bool, } @@ -19,7 +19,7 @@ type Result = std::result::Result; type Rejectable = std::result::Result; impl PgPool { - pub fn new(pg_cfg: &config::Postgres, whitelist_mode: bool) -> Result { + pub(crate) fn new(pg_cfg: &config::Postgres, whitelist_mode: bool) -> Result { let mut cfg = postgres::Config::new(); cfg.user(&pg_cfg.user) .host(&*pg_cfg.host.to_string()) @@ -40,7 +40,7 @@ impl PgPool { }) } - pub fn select_user(self, token: &Option) -> Rejectable { + pub(crate) fn select_user(self, token: &Option) -> Rejectable { let mut conn = self.conn.get().map_err(warp::reject::custom)?; if let Some(token) = token { @@ -89,7 +89,7 @@ LIMIT 1", } } - pub fn select_hashtag_id(self, tag_name: &str) -> Rejectable { + pub(crate) fn select_hashtag_id(self, tag_name: &str) -> Rejectable { let mut conn = self.conn.get().map_err(warp::reject::custom)?; conn.query("SELECT id FROM tags WHERE name = $1 LIMIT 1", &[&tag_name]) .map_err(warp::reject::custom)? @@ -102,7 +102,7 @@ LIMIT 1", /// /// **NOTE**: because we check this when the user connects, it will not include any blocks /// the user adds until they refresh/reconnect. - pub fn select_blocked_users(self, user_id: Id) -> Rejectable> { + pub(crate) fn select_blocked_users(self, user_id: Id) -> Rejectable> { let mut conn = self.conn.get().map_err(warp::reject::custom)?; conn.query( "SELECT target_account_id FROM blocks WHERE account_id = $1 @@ -114,11 +114,12 @@ LIMIT 1", .map(|row| Ok(Id(row.get(0)))) .collect() } + /// Query Postgres for everyone who has blocked the user /// /// **NOTE**: because we check this when the user connects, it will not include any blocks /// the user adds until they refresh/reconnect. - pub fn select_blocking_users(self, user_id: Id) -> Rejectable> { + pub(crate) fn select_blocking_users(self, user_id: Id) -> Rejectable> { let mut conn = self.conn.get().map_err(warp::reject::custom)?; conn.query( "SELECT account_id FROM blocks WHERE target_account_id = $1", @@ -134,7 +135,7 @@ LIMIT 1", /// /// **NOTE**: because we check this when the user connects, it will not include any blocks /// the user adds until they refresh/reconnect. - pub fn select_blocked_domains(self, user_id: Id) -> Rejectable> { + pub(crate) fn select_blocked_domains(self, user_id: Id) -> Rejectable> { let mut conn = self.conn.get().map_err(warp::reject::custom)?; conn.query( "SELECT domain FROM account_domain_blocks WHERE account_id = $1", @@ -147,7 +148,7 @@ LIMIT 1", } /// Test whether a user owns a list - pub fn user_owns_list(self, user_id: Id, list_id: i64) -> Rejectable { + pub(crate) fn user_owns_list(self, user_id: Id, list_id: i64) -> Rejectable { let mut conn = self.conn.get().map_err(warp::reject::custom)?; // For the Postgres query, `id` = list number; `account_id` = user.id let rows = &conn diff --git a/src/request/query.rs b/src/request/query.rs index c4445a9..b51bb69 100644 --- a/src/request/query.rs +++ b/src/request/query.rs @@ -4,16 +4,16 @@ use warp::filters::BoxedFilter; use warp::Filter as WarpFilter; #[derive(Debug)] -pub struct Query { - pub access_token: Option, - pub stream: String, - pub media: bool, - pub hashtag: String, - pub list: i64, +pub(crate) struct Query { + pub(crate) access_token: Option, + pub(crate) stream: String, + pub(crate) media: bool, + pub(crate) hashtag: String, + pub(crate) list: i64, } impl Query { - pub fn update_access_token( + pub(crate) fn update_access_token( self, token: Option, ) -> Result { @@ -30,17 +30,17 @@ impl Query { macro_rules! make_query_type { (Stream => $parameter:tt:$type:ty) => { #[derive(Deserialize, Debug, Default)] - pub struct Stream { - pub $parameter: $type, + pub(crate) struct Stream { + pub(crate) $parameter: $type, } }; ($name:tt => $parameter:tt:$type:ty) => { #[derive(Deserialize, Debug, Default)] - pub struct $name { - pub $parameter: $type, + pub(crate) struct $name { + pub(crate) $parameter: $type, } impl $name { - pub fn to_filter() -> BoxedFilter<(Self,)> { + pub(crate) fn to_filter() -> BoxedFilter<(Self,)> { warp::query() .or(warp::any().map(Self::default)) .unify() @@ -51,7 +51,7 @@ macro_rules! make_query_type { } make_query_type!(Media => only_media:String); impl Media { - pub fn is_truthy(&self) -> bool { + pub(crate) fn is_truthy(&self) -> bool { self.only_media == "true" || self.only_media == "1" } } @@ -65,19 +65,10 @@ impl ToString for Stream { } } -// pub fn optional_media_query() -> BoxedFilter<(Media,)> { -// warp::query() -// .or(warp::any().map(|| Media { -// only_media: "false".to_owned(), -// })) -// .unify() -// .boxed() -// } - -pub struct OptionalAccessToken; +pub(super) struct OptionalAccessToken; impl OptionalAccessToken { - pub fn from_sse_header() -> warp::filters::BoxedFilter<(Option,)> { + pub(super) fn from_sse_header() -> warp::filters::BoxedFilter<(Option,)> { let from_header = warp::header::header::("authorization").map(|auth: String| { match auth.split(' ').nth(1) { Some(s) => Some(s.to_string()), @@ -88,7 +79,7 @@ impl OptionalAccessToken { from_header.or(no_token).unify().boxed() } - pub fn from_ws_header() -> warp::filters::BoxedFilter<(Option,)> { + pub(super) fn from_ws_header() -> warp::filters::BoxedFilter<(Option,)> { let from_header = warp::header::header::("Sec-Websocket-Protocol").map(Some); let no_token = warp::any().map(|| None); diff --git a/src/request/subscription.rs b/src/request/subscription.rs index 79fd046..8b105dc 100644 --- a/src/request/subscription.rs +++ b/src/request/subscription.rs @@ -17,17 +17,17 @@ use warp::reject::Rejection; #[derive(Clone, Debug, PartialEq)] pub struct Subscription { pub timeline: Timeline, - pub allowed_langs: HashSet, - pub blocks: Blocks, - pub hashtag_name: Option, + pub(crate) allowed_langs: HashSet, + pub(crate) blocks: Blocks, + pub(crate) hashtag_name: Option, pub access_token: Option, } #[derive(Clone, Default, Debug, PartialEq)] -pub struct Blocks { - pub blocked_domains: HashSet, - pub blocked_users: HashSet, - pub blocking_users: HashSet, +pub(crate) struct Blocks { + pub(crate) blocked_domains: HashSet, + pub(crate) blocked_users: HashSet, + pub(crate) blocking_users: HashSet, } impl Default for Subscription { diff --git a/src/request/timeline.rs b/src/request/timeline.rs index e6fc9b6..b8d221a 100644 --- a/src/request/timeline.rs +++ b/src/request/timeline.rs @@ -1,5 +1,5 @@ -pub use self::err::TimelineErr; -pub use self::inner::{Content, Reach, Scope, Stream, UserData}; +pub(crate) use self::err::TimelineErr; +pub(crate) use self::inner::{Content, Reach, Scope, Stream, UserData}; use super::query::Query; use lru::LruCache; @@ -11,14 +11,14 @@ mod inner; type Result = std::result::Result; #[derive(Clone, Debug, Copy, Eq, Hash, PartialEq)] -pub struct Timeline(pub Stream, pub Reach, pub Content); +pub struct Timeline(pub(crate) Stream, pub(crate) Reach, pub(crate) Content); impl Timeline { pub fn empty() -> Self { Self(Stream::Unset, Reach::Local, Content::Notification) } - pub fn to_redis_raw_timeline(&self, hashtag: Option<&String>) -> Result { + pub(crate) fn to_redis_raw_timeline(&self, hashtag: Option<&String>) -> Result { // TODO -- does this need to account for namespaces? use {Content::*, Reach::*, Stream::*, TimelineErr::*}; @@ -46,7 +46,10 @@ impl Timeline { }) } - pub fn from_redis_text(timeline: &str, cache: &mut LruCache) -> Result { + pub(crate) fn from_redis_text( + timeline: &str, + cache: &mut LruCache, + ) -> Result { use {Content::*, Reach::*, Stream::*, TimelineErr::*}; let mut tag_id = |t: &str| cache.get(&t.to_string()).map_or(Err(BadTag), |id| Ok(*id)); @@ -65,7 +68,10 @@ impl Timeline { }) } - pub fn from_query_and_user(q: &Query, user: &UserData) -> std::result::Result { + pub(crate) fn from_query_and_user( + q: &Query, + user: &UserData, + ) -> std::result::Result { use {warp::reject::custom, Content::*, Reach::*, Scope::*, Stream::*}; Ok(match q.stream.as_ref() { diff --git a/src/request/timeline/inner.rs b/src/request/timeline/inner.rs index abe12d3..fd3a884 100644 --- a/src/request/timeline/inner.rs +++ b/src/request/timeline/inner.rs @@ -5,7 +5,7 @@ use hashbrown::HashSet; use std::convert::TryFrom; #[derive(Clone, Debug, Copy, Eq, Hash, PartialEq)] -pub enum Stream { +pub(crate) enum Stream { User(Id), List(i64), Direct(i64), @@ -15,20 +15,20 @@ pub enum Stream { } #[derive(Clone, Debug, Copy, Eq, Hash, PartialEq)] -pub enum Reach { +pub(crate) enum Reach { Local, Federated, } #[derive(Clone, Debug, Copy, Eq, Hash, PartialEq)] -pub enum Content { +pub(crate) enum Content { All, Media, Notification, } #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum Scope { +pub(crate) enum Scope { Read, Statuses, Notifications, @@ -53,10 +53,10 @@ impl TryFrom<&str> for Scope { } } -pub struct UserData { - pub id: Id, - pub allowed_langs: HashSet, - pub scopes: HashSet, +pub(crate) struct UserData { + pub(crate) id: Id, + pub(crate) allowed_langs: HashSet, + pub(crate) scopes: HashSet, } impl UserData { diff --git a/src/response.rs b/src/response.rs index 88908c7..b247dfd 100644 --- a/src/response.rs +++ b/src/response.rs @@ -3,7 +3,7 @@ pub mod redis; pub mod stream; -pub use redis::{Manager, ManagerErr}; +pub(crate) use redis::ManagerErr; #[cfg(feature = "bench")] pub use redis::msg::{RedisMsg, RedisParseOutput}; diff --git a/src/response/redis.rs b/src/response/redis.rs index 87db129..da37491 100644 --- a/src/response/redis.rs +++ b/src/response/redis.rs @@ -1,18 +1,19 @@ -pub mod connection; +mod connection; mod manager; -pub mod msg; +mod msg; -pub use connection::{RedisConn, RedisConnErr}; -pub use manager::{Manager, ManagerErr}; -pub use msg::RedisParseErr; +pub(crate) use connection::{RedisConn, RedisConnErr}; +pub use manager::Manager; +pub(crate) use manager::ManagerErr; +pub(crate) use msg::RedisParseErr; -pub enum RedisCmd { +pub(crate) enum RedisCmd { Subscribe, Unsubscribe, } impl RedisCmd { - pub fn into_sendable(self, tl: &str) -> (Vec, Vec) { + pub(crate) fn into_sendable(self, tl: &str) -> (Vec, Vec) { match self { RedisCmd::Subscribe => ( [ diff --git a/src/response/redis/connection.rs b/src/response/redis/connection.rs index 86451fc..ec0795c 100644 --- a/src/response/redis/connection.rs +++ b/src/response/redis/connection.rs @@ -1,5 +1,5 @@ mod err; -pub use err::RedisConnErr; +pub(crate) use err::RedisConnErr; use super::msg::{RedisParseErr, RedisParseOutput}; use super::{ManagerErr, RedisCmd}; @@ -18,7 +18,7 @@ use std::time::Duration; type Result = std::result::Result; #[derive(Debug)] -pub struct RedisConn { +pub(crate) struct RedisConn { primary: TcpStream, secondary: TcpStream, redis_namespace: Option, @@ -29,7 +29,7 @@ pub struct RedisConn { } impl RedisConn { - pub fn new(redis_cfg: &Redis) -> Result { + pub(crate) fn new(redis_cfg: &Redis) -> Result { let addr = [&*redis_cfg.host, ":", &*redis_cfg.port.to_string()].concat(); let conn = Self::new_connection(&addr, redis_cfg.password.as_ref())?; @@ -50,7 +50,7 @@ impl RedisConn { Ok(redis_conn) } - pub fn poll_redis(&mut self) -> Poll, ManagerErr> { + pub(crate) fn poll_redis(&mut self) -> Poll, ManagerErr> { loop { match self.primary.read(&mut self.redis_input[self.cursor..]) { Ok(n) => { @@ -108,26 +108,15 @@ impl RedisConn { self.redis_input[acc] = cur.expect("TODO"); acc + 1 }); - - // self.cursor = 0; - // for (i, byte) in [leftover.as_bytes(), invalid_bytes] - // .concat() - // .bytes() - // .enumerate() - // { - // self.redis_input[i] = byte.expect("TODO"); - // self.cursor += 1; - // } - res } - pub fn update_cache(&mut self, hashtag: String, id: i64) { + pub(crate) fn update_cache(&mut self, hashtag: String, id: i64) { self.tag_id_cache.put(hashtag.clone(), id); self.tag_name_cache.put(id, hashtag); } - pub fn send_cmd(&mut self, cmd: RedisCmd, timeline: &Timeline) -> Result<()> { + pub(crate) fn send_cmd(&mut self, cmd: RedisCmd, timeline: &Timeline) -> Result<()> { let hashtag = match timeline { Timeline(Stream::Hashtag(id), _, _) => self.tag_name_cache.get(id), _non_hashtag_timeline => None, diff --git a/src/response/redis/connection/err.rs b/src/response/redis/connection/err.rs index ec945d8..0707597 100644 --- a/src/response/redis/connection/err.rs +++ b/src/response/redis/connection/err.rs @@ -13,7 +13,7 @@ pub enum RedisConnErr { } impl RedisConnErr { - pub fn with_addr>(address: T, inner: std::io::Error) -> Self { + pub(crate) fn with_addr>(address: T, inner: std::io::Error) -> Self { Self::ConnectionErr { addr: address.as_ref().to_string(), inner, diff --git a/src/response/redis/manager.rs b/src/response/redis/manager.rs index a51cacd..afb4795 100644 --- a/src/response/redis/manager.rs +++ b/src/response/redis/manager.rs @@ -2,7 +2,7 @@ //! polled by the correct `ClientAgent`. Also manages sububscriptions and //! unsubscriptions to/from Redis. mod err; -pub use err::ManagerErr; +pub(crate) use err::ManagerErr; use super::{RedisCmd, RedisConn}; use crate::config; @@ -68,7 +68,7 @@ impl Manager { }; } - pub fn unsubscribe(&mut self, tl: Timeline) -> Result<()> { + pub(crate) fn unsubscribe(&mut self, tl: Timeline) -> Result<()> { let number_of_subscriptions = self .clients_per_timeline .entry(tl) diff --git a/src/response/redis/msg.rs b/src/response/redis/msg.rs index cf9f336..bfa2344 100644 --- a/src/response/redis/msg.rs +++ b/src/response/redis/msg.rs @@ -19,28 +19,24 @@ //! Read that as: an array with three elements: the first element is a bulk string with //! three characters, the second is a bulk string with ten characters, and the third is a //! bulk string with 1,386 characters. +use self::RedisParseOutput::*; +pub use err::RedisParseErr; +use std::convert::{TryFrom, TryInto}; +use std::str; mod err; -pub use err::RedisParseErr; - -use self::RedisParseOutput::*; - -use std::{ - convert::{TryFrom, TryInto}, - str, -}; #[derive(Debug, Clone, PartialEq)] -pub enum RedisParseOutput<'a> { +pub(crate) enum RedisParseOutput<'a> { Msg(RedisMsg<'a>), NonMsg(&'a str), } #[derive(Debug, Clone, PartialEq)] -pub struct RedisMsg<'a> { - pub timeline_txt: &'a str, - pub event_txt: &'a str, - pub leftover_input: &'a str, +pub(crate) struct RedisMsg<'a> { + pub(crate) timeline_txt: &'a str, + pub(crate) event_txt: &'a str, + pub(crate) leftover_input: &'a str, } impl<'a> TryFrom<&'a str> for RedisParseOutput<'a> {