chiark / gitweb /
tz compiles but not finished
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 16 Oct 2020 22:03:41 +0000 (23:03 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 16 Oct 2020 22:03:41 +0000 (23:03 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/cmdlistener.rs
src/gamestate.rs
src/tz.rs

index 6bad6eaeb1651d96ebb7955f3cb9d68bcacbb74d..7e84e8cebae5380bebb9416117bebf8da80e8d14 100644 (file)
@@ -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 },
index 792b76cd0d09dd5b4e5d51bc05a5d6bb0102c456..7e296629d57271e0a87a2200bc89ea7ff80c2d5b 100644 (file)
@@ -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
   }
index 81cbda5584ed16ab88e58e5b50925818fac71983..a2c4f65517ba3f9a2f073e87eb8bdb0948898a3f 100644 (file)
--- 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<dyn TimeFormatter>);
+pub struct Timezone (Arc<ChronoTz>);
 
-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<TZ: chrono::TimeZone> {
+#[derive(Clone,Debug,Default)]
+struct ChronoTz {
   name: String,
-  ctz: TZ,
+  ctz: Option<chrono_tz::Tz>,
 }
   
-impl<TZ: chrono::TimeZone + Debug + Sync + Send> TimeFormatter for ChronoTz<TZ> {
-  fn name(&self) -> &str { &self.name() }
-
+impl Timezone {
+  pub fn name(&self) -> &str {
+    &self.0.name
+  }
   #[throws(fmt::Error)]
-  fn format<W: io::Write>(&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<W: fmt::Write>(&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<Option<HashMap<String, Timezone>>> = const_rwlock(None);
+type MemoTable = Option<HashMap<String, Timezone>>;
+static MEMO: RwLock<MemoTable> = 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() }))
   }
 }