chiark / gitweb /
wip timezone
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 16 Oct 2020 22:20:03 +0000 (23:20 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Fri, 16 Oct 2020 22:20:03 +0000 (23:20 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/bin/otter.rs
src/cmdlistener.rs
src/commands.rs
src/spec.rs
src/tz.rs

index e51b0449cdd51f40fd9bd50edc0049a5c4499539..cf28f2d2d5d37f82e69eb5202e0c7857e5bfc785 100644 (file)
@@ -361,9 +361,16 @@ fn setup_table(ma: &MainOpts, chan: &mut ConnForGame,
         Err(anyhow!("duplicate player nick {:?} in spec", &pspec.nick))?;
       }
       st.new = true;
+      let timezone = pspec.timezone.as_ref().or(
+        spec.timezone.as_ref()
+      ).cloned();
+      // ^ todo use client program timezone?
       if !st.old {
-        insns.push(MgmtGameInstruction::AddPlayer(PlayerState {
-          nick: pspec.nick.clone()
+        insns.push(MgmtGameInstruction::AddPlayer(MgmtPlayerState {
+          timezone,
+          st: PlayerState {
+            nick: pspec.nick.clone(),
+          },
         }));
       }
     }
index 7e84e8cebae5380bebb9416117bebf8da80e8d14..9a7f7d32ed14edc7121d7a59b460085d2e7bc7dc 100644 (file)
@@ -159,15 +159,20 @@ fn execute_game_insn(cs: &CommandStream,
     }
 
     Insn::AddPlayer(pl) => {
-      if ig.gs.players.values().any(|p| p.nick == pl.nick) {
+      if ig.gs.players.values().any(|p| p.nick == pl.st.nick) {
         Err(ME::AlreadyExists)?;
       }
       let logentry = LogEntry {
         html: Html(format!("{} added a player: {}", &who,
-                      htmlescape::encode_minimal(&pl.nick))),
+                      htmlescape::encode_minimal(&pl.st.nick))),
       };
-      let tz = Timezone::default_todo();
-      let (player, logentry) = ig.player_new(pl, tz, logentry)?;
+      let timezone = pl.timezone.as_ref().map(String::as_str)
+        .unwrap_or("");
+      let tz = match Timezone::from_str(timezone) {
+        Ok(tz) => tz,
+        Err(x) => x, // x is of type !
+      };
+      let (player, logentry) = ig.player_new(pl.st, tz, logentry)?;
       (U{ pcs: vec![],
           log: vec![ logentry ],
           raw: None },
index f39e038af0933a7666ac12417f54f591d1a5b739..dbf2fd4bd51ad5d59abce5f0d71b27b542368b6c 100644 (file)
@@ -39,13 +39,19 @@ pub enum MgmtGameInstruction {
   AddPieces(PiecesSpec),
   DeletePiece(PieceId),
 
-  AddPlayer(PlayerState),
+  AddPlayer(MgmtPlayerState),
   RemovePlayer(PlayerId),
   ResetPlayerAccesses { players: Vec<PlayerId> },
   ReportPlayerAccesses { players: Vec<PlayerId> },
   SetFixedPlayerAccess { player: PlayerId, token: RawToken },
 }
 
+#[derive(Debug,Serialize,Deserialize)]
+pub struct MgmtPlayerState {
+  pub timezone: Option<String>,
+  #[serde(flatten)] pub st: PlayerState,
+}
+
 #[derive(Debug,Serialize,Deserialize)]
 pub enum MgmtGameResponse {
   Fine,
index 5380d0fab8c38ec003ebc976e3a09b416ee5f2f7..5002452e5db90a98d789c050263cd1bf238f1dc3 100644 (file)
@@ -56,11 +56,13 @@ display_as_debug!{SpecError}
 #[derive(Debug,Serialize,Deserialize)]
 pub struct TableSpec {
   pub players : Vec<PlayerSpec>,
+  pub timezone: Option<String>, // default for player timezones
 }
 
 #[derive(Debug,Serialize,Deserialize)]
 pub struct PlayerSpec {
   pub nick: String,
+  pub timezone: Option<String>,
   #[serde(flatten)]
   pub access: Option<Box<dyn PlayerAccessSpec>>,
 }
index a2c4f65517ba3f9a2f073e87eb8bdb0948898a3f..04c7e20d7403a9b8b2a79fa0b85a678a057a67d9 100644 (file)
--- a/src/tz.rs
+++ b/src/tz.rs
@@ -9,10 +9,10 @@ use parking_lot::{RwLock, const_rwlock};
 #[derive(SerializeDisplay)]
 #[derive(DeserializeFromStr)]
 #[derive(Clone,Debug)]
-pub struct Timezone (Arc<ChronoTz>);
+pub struct Timezone (Arc<TzInfo>);
 
 #[derive(Clone,Debug,Default)]
-struct ChronoTz {
+struct TzInfo {
   name: String,
   ctz: Option<chrono_tz::Tz>,
 }
@@ -60,11 +60,11 @@ impl FromStr for Timezone {
       let name = name.to_string();
       match chrono_tz::Tz::from_str(&name) {
         Ok(ctz) => {
-          Arc::new(ChronoTz { name, ctz: Some(ctz) })
+          Arc::new(TzInfo { name, ctz: Some(ctz) })
         },
         Err(emsg) => {
           error!("Error loading timezone {:?}: {}, using UTC", name, emsg);
-          Arc::new(ChronoTz { name, ctz: None })
+          Arc::new(TzInfo { name, ctz: None })
         },
       }
     };
@@ -77,6 +77,6 @@ impl FromStr for Timezone {
 
 impl Default for Timezone {
   fn default() -> Self {
-    Timezone(Arc::new(ChronoTz { ctz: None, name: default() }))
+    Timezone(Arc::new(TzInfo { ctz: None, name: default() }))
   }
 }