From 7d5a022f4a4927a65226e61019355ceae97db083 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Fri, 16 Oct 2020 23:03:41 +0100 Subject: [PATCH] tz compiles but not finished Signed-off-by: Ian Jackson --- src/cmdlistener.rs | 3 +- src/gamestate.rs | 2 +- src/tz.rs | 105 ++++++++++++++++++--------------------------- 3 files changed, 44 insertions(+), 66 deletions(-) diff --git a/src/cmdlistener.rs b/src/cmdlistener.rs index 6bad6eae..7e84e8ce 100644 --- a/src/cmdlistener.rs +++ b/src/cmdlistener.rs @@ -166,7 +166,8 @@ fn execute_game_insn(cs: &CommandStream, html: Html(format!("{} added a player: {}", &who, htmlescape::encode_minimal(&pl.nick))), }; - let (player, logentry) = ig.player_new(pl, Timezone{}, logentry)?; + let tz = Timezone::default_todo(); + let (player, logentry) = ig.player_new(pl, tz, logentry)?; (U{ pcs: vec![], log: vec![ logentry ], raw: None }, diff --git a/src/gamestate.rs b/src/gamestate.rs index 792b76cd..7e296629 100644 --- a/src/gamestate.rs +++ b/src/gamestate.rs @@ -171,7 +171,7 @@ impl Timestamp { } pub fn render(&self, tz: &Timezone) -> String { - let s = String::with_capacity(30); + let mut s = String::with_capacity(30); tz.format(*self, &mut s).unwrap(); s } diff --git a/src/tz.rs b/src/tz.rs index 81cbda55..a2c4f655 100644 --- a/src/tz.rs +++ b/src/tz.rs @@ -9,97 +9,74 @@ use parking_lot::{RwLock, const_rwlock}; #[derive(SerializeDisplay)] #[derive(DeserializeFromStr)] #[derive(Clone,Debug)] -pub struct Timezone (Arc); +pub struct Timezone (Arc); -impl Timezone { - delegate! { to self.0 { - pub fn format(&self, ts: Timestamp, f: &mut Formatter) -> fmt::Result; - } } -} - -pub trait TimeFormatter : Debug + Sync + Send { - fn format(&self, ts: Timestamp, f: &mut Formatter) -> fmt::Result; - fn name(&self) -> &str; -} - -impl Display for Timezone { - #[throws(fmt::Error)] - fn fmt(&self, f: &mut Formatter) { - write!(f, "{}", self.0.name())?; - } -} - -#[derive(Clone,Debug,Default,Serialize,Deserialize)] -struct ChronoTz { +#[derive(Clone,Debug,Default)] +struct ChronoTz { name: String, - ctz: TZ, + ctz: Option, } -impl TimeFormatter for ChronoTz { - fn name(&self) -> &str { &self.name() } - +impl Timezone { + pub fn name(&self) -> &str { + &self.0.name + } #[throws(fmt::Error)] - fn format(&self, ts: Timestamp, f: &mut W) { - write!(f, "TS{}(@{:?})", ts, &self); - -/* #[derive(Error,Debug)] - enum E { - #[from] SystemTime(SystemTimeError); - #[from] Other(&'static str); - }; + pub fn format(&self, ts: Timestamp, w: &mut W) { + write!(w, "TS{:?}(@{:?})", ts, &self)? +// let ctz = chrono::offset::Utc; + } - (||{ - let then = SytemTime::UNIX_EPOCH.checked_add( - Duration::from_secs(tz.0) - ).ok_or("SystemTime wrap error!")?; - let elapsed = then.elapsed()?; - if elapsed > 86400/2 { - - } - let now = SystemTime::now(); - let elapsed = now.duration_since(then); - - None => format!("TS{}(@{:?})", self.0, tz) + pub fn default_todo() -> Self { + Timezone::from_str("").unwrap() } -*/ +} +impl Display for Timezone { + #[throws(fmt::Error)] + fn fmt(&self, f: &mut Formatter) { + write!(f, "{}", &self.0.name)?; } } -static memo: RwLock>> = const_rwlock(None); +type MemoTable = Option>; +static MEMO: RwLock = const_rwlock(None); impl FromStr for Timezone { type Err = !; #[throws(!)] fn from_str(name: &str) -> Self { - let get = |memor| memor?.get(name).map(Clone::clone); - if let Some(got) = get(memo(), name) { return got } + if name.is_empty() { return default() } + + let get = |memor: &MemoTable| memor.as_ref()?.get(name).map(Clone::clone); + if let Some(got) = get(&MEMO.read()) { return got } // slow path - let memow = memo.write(); - if let Some(got) = get(memow) { return got } + let mut memow = MEMO.write(); + if let Some(got) = get(&memow) { return got } // really slow path - let name = name.to_string(); - let out = match chrono_tz::Tz::from_str(name) { - Ok(ctz) => { - Arc::new(ChronoTz { ctz, name }) - }, - Err(emsg) => { - error!("Error loading timezone {:?}: {}, using UTC", name, emsg); - let ctz = chrono::offset::Utc; - Arc::new(ChronoTz { ctz, name }) - }, + let out = { + let name = name.to_string(); + match chrono_tz::Tz::from_str(&name) { + Ok(ctz) => { + Arc::new(ChronoTz { name, ctz: Some(ctz) }) + }, + Err(emsg) => { + error!("Error loading timezone {:?}: {}, using UTC", name, emsg); + Arc::new(ChronoTz { name, ctz: None }) + }, + } }; + let out = Timezone(out); memow.get_or_insert_with(default) - .set(name.to_string(), out.clone()); + .insert(name.to_string(), out.clone()); out } } impl Default for Timezone { fn default() -> Self { - let ctz = chrono::offset::Utc; - Arc::new(ChronoTz { ctz, name: default() }) + Timezone(Arc::new(ChronoTz { ctz: None, name: default() })) } } -- 2.30.2