From: Ian Jackson Date: Sat, 28 Nov 2020 00:39:24 +0000 (+0000) Subject: wip split off daemon/, before revert X-Git-Tag: otter-0.2.0~310 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=7b6c42eb3e71ee3094009bf7c494ad4d68c88a23;p=otter.git wip split off daemon/, before revert Signed-off-by: Ian Jackson --- diff --git a/src/accounts.rs b/daemon/accounts.rs similarity index 97% rename from src/accounts.rs rename to daemon/accounts.rs index 789d019b..c2367a24 100644 --- a/src/accounts.rs +++ b/daemon/accounts.rs @@ -8,29 +8,10 @@ use parking_lot::{Mutex, const_mutex, MutexGuard}; //---------- simple types ---------- -slotmap::new_key_type!{ - pub struct AccountId; -} - -#[derive(Debug,Clone,Deserialize,Serialize)] -#[derive(Eq,PartialEq,Ord,PartialOrd,Hash)] -pub enum AccountScope { - Server, - Unix { user : String }, -} - type AS = AccountScope; type ME = MgmtError; type IE = InternalError; -#[derive(Debug,Clone)] -#[derive(Eq,PartialEq,Ord,PartialOrd,Hash)] -#[derive(DeserializeFromStr,SerializeDisplay)] -pub struct AccountName { - pub scope: AccountScope, - pub subaccount: String, -} - /// Record of acess for a player. Newtype prevents mutable access /// without invalidating old tokens and permissions check. #[derive(Serialize,Deserialize,Debug)] @@ -575,4 +556,10 @@ pub mod loaded_acl { ).collect() } } } + + impl Perm for spec::TablePermission { + type Auth = InstanceName; + const TEST_EXISTENCE : Self = TablePermission::TestExistence; + const NOT_FOUND : MgmtError = MgmtError::GameNotFound; + } } diff --git a/src/api.rs b/daemon/api.rs similarity index 100% rename from src/api.rs rename to daemon/api.rs diff --git a/daemon/error.rs b/daemon/error.rs new file mode 100644 index 00000000..24742b0c --- /dev/null +++ b/daemon/error.rs @@ -0,0 +1,97 @@ +// Copyright 2020 Ian Jackson +// SPDX-License-Identifier: AGPL-3.0-or-later +// There is NO WARRANTY. + +use crate::imports::*; + +#[derive(Error,Debug)] +pub enum OnlineError { + #[error("Game in process of being destroyed")] + GameBeingDestroyed, + #[error("client session not recognised (terminated by server?)")] + NoClient, + #[error("player not part of game (removed?)")] + NoPlayer(#[from] PlayerNotFound), + #[error("invalid Z coordinate")] + InvalidZCoord, + #[error("Server operational problems - consult administrator: {0:?}")] + ServerFailure(#[from] InternalError), + #[error("JSON deserialisation error: {0:?}")] + BadJSON(serde_json::Error), + #[error("referenced piece is gone (maybe race)")] + PieceGone, + #[error("improper piece hold status for op (maybe race)")] + PieceHeld, + #[error("improper UI operation")] + BadOperation, +} +from_instance_lock_error!{OnlineError} + +pub use OnlineError::{NoClient,NoPlayer}; + +#[derive(Error,Debug)] +pub enum InstanceLockError { + GameCorrupted, + GameBeingDestroyed, +} +#[macro_export] +macro_rules! from_instance_lock_error { + ($into:ident) => { + impl From for $into { + fn from(e: InstanceLockError) -> $into { + use InstanceLockError::*; + match e { + GameBeingDestroyed => $into::GameBeingDestroyed, + GameCorrupted => InternalError::GameCorrupted.into(), + } + } + } + } +} + +pub trait ById { + type Id; + type Entry; + type Error; + #[throws(Self::Error)] + fn byid(&self, t: Self::Id) -> &Self::Entry; + #[throws(Self::Error)] + fn byid_mut(&mut self, t: Self::Id) -> &mut Self::Entry; +} + +pub trait IdForById { + type Error; + #[allow(clippy::declare_interior_mutable_const)] +// https://github.com/rust-lang/rust-clippy/issues/3962#issuecomment-667957112 + const ERROR : Self::Error; +} + +macro_rules! some_slotmap { + ($slotmap:ident) => { + impl ById for $slotmap { + type Id = I; + type Entry = T; + type Error = ::Error; + fn byid (& self, t: Self::Id) -> Result<& T, Self::Error> { + self.get (t).ok_or(::ERROR) + } + fn byid_mut(&mut self, t: Self::Id) -> Result<&mut T, Self::Error> { + self.get_mut(t).ok_or(::ERROR) + } + } + } +} + +some_slotmap!{DenseSlotMap} +some_slotmap!{SecondarySlotMap} + +impl IdForById for T where T : AccessId { + type Error = T::Error; + const ERROR : Self::Error = ::ERROR; +} + +impl IdForById for PieceId { + type Error = OE; + const ERROR : OE = OE::PieceGone; +} + diff --git a/src/gamestate.rs b/daemon/gamestate.rs similarity index 96% rename from src/gamestate.rs rename to daemon/gamestate.rs index dcab0298..0bd7c775 100644 --- a/src/gamestate.rs +++ b/daemon/gamestate.rs @@ -6,19 +6,6 @@ use crate::imports::*; // ---------- newtypes and type aliases ---------- -visible_slotmap_key!{ PlayerId('#') } - -slotmap::new_key_type!{ - pub struct PieceId; -} - -#[derive(Copy,Clone,Debug,Ord,PartialOrd,Eq,PartialEq)] -#[derive(Serialize,Deserialize)] -#[serde(transparent)] -pub struct Generation (pub u64); - -visible_slotmap_key!{ VisiblePieceId('.') } - #[derive(Clone,Serialize,Deserialize,Hash,Eq,Ord,PartialEq,PartialOrd)] #[serde(transparent)] pub struct Html (pub String); diff --git a/src/global.rs b/daemon/global.rs similarity index 100% rename from src/global.rs rename to daemon/global.rs diff --git a/daemon/imports.rs b/daemon/imports.rs new file mode 100644 index 00000000..8711b25e --- /dev/null +++ b/daemon/imports.rs @@ -0,0 +1,27 @@ +// Copyright 2020 Ian Jackson +// SPDX-License-Identifier: AGPL-3.0-or-later +// There is NO WARRANTY. + +use otter::imports::*; + +pub mod session; +pub mod updates; +pub mod sse; +pub mod api; +pub mod cmdlistener; +pub mod global; +pub mod accounts; +pub mod gamestate; + +pub use crate::gamestate::*; +pub use crate::updates::*; +pub use crate::sse; +pub use crate::cmdlistener::*; +pub use crate::global::*; +pub use crate::accounts::*; +pub use crate::accounts::loaded_acl::{self,LoadedAcl,EffectiveACL,PermSet}; + +pub use crate::api::{Lens,TransparentLens,ApiPieceOpError}; +pub use crate::api::{PresentationLayout,AbbrevPresentationLayout}; + +pub type OE = OnlineError; diff --git a/daemon/main.rs b/daemon/main.rs index 57561c56..67403d55 100644 --- a/daemon/main.rs +++ b/daemon/main.rs @@ -9,7 +9,7 @@ use rocket_contrib::serve::StaticFiles; use rocket::response::Content; use rocket::fairing; -use otter::imports::*; +pub mod imports; #[derive(Serialize,Debug)] struct FrontPageRenderContext { } diff --git a/src/sse.rs b/daemon/sse.rs similarity index 100% rename from src/sse.rs rename to daemon/sse.rs diff --git a/src/updates.rs b/daemon/updates.rs similarity index 100% rename from src/updates.rs rename to daemon/updates.rs diff --git a/src/commands.rs b/src/commands.rs index 1e08f922..3a1a6dee 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -4,6 +4,23 @@ use crate::imports::*; +//---------- basic types ---------- + +visible_slotmap_key!{ PlayerId('#') } + +slotmap::new_key_type!{ + pub struct PieceId; +} + +#[derive(Copy,Clone,Debug,Ord,PartialOrd,Eq,PartialEq)] +#[derive(Serialize,Deserialize)] +#[serde(transparent)] +pub struct Generation (pub u64); + +visible_slotmap_key!{ VisiblePieceId('.') } + +//---------- command ---------- + #[derive(Debug,Serialize,Deserialize)] pub enum MgmtCommand { Noop, diff --git a/src/error.rs b/src/error.rs index 47ccdf98..cb2cb2b0 100644 --- a/src/error.rs +++ b/src/error.rs @@ -6,29 +6,6 @@ use crate::imports::*; type IE = InternalError; -#[derive(Error,Debug)] -pub enum OnlineError { - #[error("Game in process of being destroyed")] - GameBeingDestroyed, - #[error("client session not recognised (terminated by server?)")] - NoClient, - #[error("player not part of game (removed?)")] - NoPlayer(#[from] PlayerNotFound), - #[error("invalid Z coordinate")] - InvalidZCoord, - #[error("Server operational problems - consult administrator: {0:?}")] - ServerFailure(#[from] InternalError), - #[error("JSON deserialisation error: {0:?}")] - BadJSON(serde_json::Error), - #[error("referenced piece is gone (maybe race)")] - PieceGone, - #[error("improper piece hold status for op (maybe race)")] - PieceHeld, - #[error("improper UI operation")] - BadOperation, -} -from_instance_lock_error!{OnlineError} - #[derive(Error,Debug)] pub enum InternalError { #[error("Game corrupted by previous crash")] @@ -86,74 +63,6 @@ display_as_debug!{PieceOpError} pub type StartupError = anyhow::Error; -pub use OnlineError::{NoClient,NoPlayer}; - -#[derive(Error,Debug)] -pub enum InstanceLockError { - GameCorrupted, - GameBeingDestroyed, -} -#[macro_export] -macro_rules! from_instance_lock_error { - ($into:ident) => { - impl From for $into { - fn from(e: InstanceLockError) -> $into { - use InstanceLockError::*; - match e { - GameBeingDestroyed => $into::GameBeingDestroyed, - GameCorrupted => InternalError::GameCorrupted.into(), - } - } - } - } -} - -pub trait ById { - type Id; - type Entry; - type Error; - #[throws(Self::Error)] - fn byid(&self, t: Self::Id) -> &Self::Entry; - #[throws(Self::Error)] - fn byid_mut(&mut self, t: Self::Id) -> &mut Self::Entry; -} - -pub trait IdForById { - type Error; - #[allow(clippy::declare_interior_mutable_const)] -// https://github.com/rust-lang/rust-clippy/issues/3962#issuecomment-667957112 - const ERROR : Self::Error; -} - -macro_rules! some_slotmap { - ($slotmap:ident) => { - impl ById for $slotmap { - type Id = I; - type Entry = T; - type Error = ::Error; - fn byid (& self, t: Self::Id) -> Result<& T, Self::Error> { - self.get (t).ok_or(::ERROR) - } - fn byid_mut(&mut self, t: Self::Id) -> Result<&mut T, Self::Error> { - self.get_mut(t).ok_or(::ERROR) - } - } - } -} - -some_slotmap!{DenseSlotMap} -some_slotmap!{SecondarySlotMap} - -impl IdForById for T where T : AccessId { - type Error = T::Error; - const ERROR : Self::Error = ::ERROR; -} - -impl IdForById for PieceId { - type Error = OE; - const ERROR : OE = OE::PieceGone; -} - #[macro_export] macro_rules! display_as_debug { {$x:ty} => { diff --git a/src/imports.rs b/src/imports.rs index 2332c73d..8e6f1cc0 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -87,27 +87,18 @@ pub use vecdeque_stableix::Deque as StableIndexVecDeque; pub use zcoord::{self, ZCoord}; -pub use crate::global::*; -pub use crate::gamestate::*; pub use crate::pieces::*; pub use crate::keydata::*; -pub use crate::updates::*; -pub use crate::sse; pub use crate::error::*; pub use crate::commands::*; pub use crate::slotmap_slot_idx::*; -pub use crate::cmdlistener::*; pub use crate::mgmtchannel::*; -pub use crate::api::{Lens,TransparentLens,ApiPieceOpError}; -pub use crate::api::{PresentationLayout,AbbrevPresentationLayout}; pub use crate::utils::*; pub use crate::spec::*; pub use crate::debugreader::DebugReader; pub use crate::shapelib; pub use crate::tz::*; pub use crate::config::*; -pub use crate::accounts::*; -pub use crate::accounts::loaded_acl::{self,LoadedAcl,EffectiveACL,PermSet}; pub use crate::toml_de; pub type SecondarySlotMap = slotmap::secondary::SecondaryMap; @@ -121,4 +112,3 @@ pub enum Impossible { } display_as_debug!(Impossible); pub type AE = anyhow::Error; -pub type OE = OnlineError; diff --git a/src/lib.rs b/src/lib.rs index b8f51b70..3e2fb15e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,24 +8,16 @@ #![allow(clippy::redundant_closure_call)] pub mod imports; -pub mod global; pub mod pieces; -pub mod gamestate; pub mod keydata; -pub mod updates; -pub mod sse; pub mod error; -pub mod session; -pub mod api; pub mod spec; -pub mod cmdlistener; pub mod commands; pub mod utils; pub mod mgmtchannel; pub mod debugreader; pub mod shapelib; pub mod tz; -pub mod accounts; pub mod config; #[path="toml-de.rs"] pub mod toml_de; #[path="slotmap-slot-idx.rs"] pub mod slotmap_slot_idx; diff --git a/src/spec.rs b/src/spec.rs index 98e2a5e0..185028c2 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -5,6 +5,8 @@ // game specs use serde::{Serialize,Deserialize}; +use serde_with::DeserializeFromStr; +use serde_with::SerializeDisplay; use fehler::throws; use index_vec::{define_index_type,IndexVec}; use crate::gamestate::PieceSpec; @@ -12,7 +14,6 @@ use std::fmt::Debug; use std::collections::hash_set::HashSet; use thiserror::Error; use crate::error::display_as_debug; -use crate::accounts::AccountName; use std::hash::Hash; use num_derive::{ToPrimitive, FromPrimitive}; @@ -61,6 +62,27 @@ pub enum SpecError { } display_as_debug!{SpecError} +//---------- Accounts ---------- + +slotmap::new_key_type!{ + pub struct AccountId; +} + +#[derive(Debug,Clone,Deserialize,Serialize)] +#[derive(Eq,PartialEq,Ord,PartialOrd,Hash)] +pub enum AccountScope { + Server, + Unix { user : String }, +} + +#[derive(Debug,Clone)] +#[derive(Eq,PartialEq,Ord,PartialOrd,Hash)] +#[derive(DeserializeFromStr,SerializeDisplay)] +pub struct AccountName { + pub scope: AccountScope, + pub subaccount: String, +} + //---------- Table TOML file ---------- #[derive(Debug,Serialize,Deserialize)] @@ -275,12 +297,6 @@ pub mod implementation { } } - impl loaded_acl::Perm for TablePermission { - type Auth = InstanceName; - const TEST_EXISTENCE : Self = TablePermission::TestExistence; - const NOT_FOUND : MgmtError = MgmtError::GameNotFound; - } - impl TablePlayerSpec { pub fn account_glob(&self) -> String { fn scope_glob(scope: AccountScope) -> String {