From: Ian Jackson Date: Thu, 12 Nov 2020 00:03:36 +0000 (+0000) Subject: wip thunk X-Git-Tag: otter-0.2.0~541 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=04ab93a7441eab9149f4b2f8b8932df812ea893e;p=otter.git wip thunk Signed-off-by: Ian Jackson --- diff --git a/Cargo.lock.example b/Cargo.lock.example index 63c51092..7a7e0f68 100644 --- a/Cargo.lock.example +++ b/Cargo.lock.example @@ -854,6 +854,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" +[[package]] +name = "lazy-init" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671025f3cc9b5d5188eca51493d8097e6cd1dc3828e0a59f7befbaaf56e930ab" + [[package]] name = "lazy_static" version = "1.4.0" @@ -1110,6 +1116,7 @@ dependencies = [ "index_vec", "inventory", "itertools", + "lazy-init", "lazy_static", "libc", "log 0.4.11", diff --git a/Cargo.toml b/Cargo.toml index 04d6d503..edb4edc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ inventory = "0.1" itertools = "0.9" lazy_static = "1" libc = "0.2" +lazy-init = "0.4" log = "0.4" nix = "0.18" num-derive = "0.3" diff --git a/src/bin/otter.rs b/src/bin/otter.rs index b7118ae6..5efb3208 100644 --- a/src/bin/otter.rs +++ b/src/bin/otter.rs @@ -128,7 +128,7 @@ fn parse_args( mem::drop(ap); let completed = completer(parsed).unwrap_or_else(|e:ArgumentParseError| { - let ap = apmaker(&mut Default::default()); + let ap = apmaker(&mut default()); ap.error(&us, &e.0, &mut stderr); exit(EXIT_USAGE); }); @@ -194,16 +194,13 @@ fn main() { }) })?; let gaccount = gaccount.unwrap_or_else(|| account.clone()); - let mut config_store : Option,APE>> = None; - let config = ||{ - Ok::<_,APE>(&config_store.unwrap_or_else(||{ - ServerConfig::read(config_filename.as_ref().map(String::as_str)) - .context("read config file")?; - Ok(otter::global::config()) - })?) - }; + let config = Thunk::new(||{ + ServerConfig::read(config_filename.as_ref().map(String::as_str)) + .context("read config file")?; + Ok(otter::global::config()) + }); let socket_path = socket_path.map(Ok::<_,APE>).unwrap_or_else(||{ - Ok(config()?.command_socket.clone()) + Ok(config?.command_socket.clone()) })?; Ok((subcommand, subargs, MainOpts { account, @@ -377,7 +374,7 @@ const PLAYER_DEFAULT_PERMS : &[TablePermission] = &[ ]; #[throws(AE)] -fn setup_table(ma: &MainOpts, spec: &TableSpec) -> Vec { +fn setup_table(_ma: &MainOpts, spec: &TableSpec) -> Vec { let TableSpec { players, player_perms, acl } = spec; let mut player_perms = player_perms.clone() .unwrap_or(PLAYER_DEFAULT_PERMS.iter().cloned().collect()); @@ -390,7 +387,7 @@ fn setup_table(ma: &MainOpts, spec: &TableSpec) -> Vec { deny: default(), }) .chain( - spec.acl.ents.iter().cloned() + acl.ents.iter().cloned() ) .collect(); diff --git a/src/utils.rs b/src/utils.rs index 2132a74d..87a98572 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,8 +2,10 @@ // SPDX-License-Identifier: AGPL-3.0-or-later // There is NO WARRANTY. +use std::fmt::{self, Debug}; use std::fs; use std::io; +use std::ops::Deref; use std::os::unix::io::IntoRawFd; use fehler::{throw, throws}; @@ -52,3 +54,42 @@ impl LocalFileExt for fs::File { } } } + +// todo #[derive(Clone)] +pub struct Thunk U> ( + lazy_init::LazyTransform +); + +impl T> Debug for Thunk where T: Debug{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.0.get() { + Some(inner) => write!(f, "Thunk({:?})", inner), + None => write!(f, "Thunk(...)"), + } + } +} + +impl T> Thunk { + pub fn new(f: F) -> Self { + Thunk( + lazy_init::LazyTransform::new(f) + ) + } + pub fn force_eval(thunk: &Self) { + thunk.0.get_or_create(|f| f()); + } + pub fn into_inner(thunk: Self) -> T { + Thunk::force_eval(&thunk); + thunk.0.into_inner().unwrap_or_else(|_|panic!()) + } +} + +impl T> Deref for Thunk { + type Target = T; + fn deref(&self) -> &T { + Thunk::force_eval(self); + self.0.get().unwrap() + } +} + +// todo: DerefMut