chiark / gitweb /
newtype RawTokenVal
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 5 Sep 2020 22:53:03 +0000 (23:53 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 5 Sep 2020 22:53:03 +0000 (23:53 +0100)
src/api.rs
src/bin/server.rs
src/global.rs
src/session.rs
src/spec.rs

index b0da887ac3dae8845b0cecebb88a19ee557a84a0..75e8f0efc1b7789d5e1678555f1ab88473f74135 100644 (file)
@@ -4,7 +4,7 @@ use crate::http::*;
 
 #[derive(Debug,Serialize,Deserialize)]
 struct ApiPiece<O : ApiPieceOp> {
-  ctoken : String,
+  ctoken : RawToken,
   piece : VisiblePieceId,
   gen : Generation,
   cseq : ClientSequence,
@@ -66,7 +66,7 @@ impl Lens for TransparentLens {
 fn api_piece_op<O: ApiPieceOp>(form : Json<ApiPiece<O>>)
                    -> impl response::Responder<'static> {
 //  thread::sleep(Duration::from_millis(2000));
-  let iad = lookup_token(&form.ctoken)?;
+  let iad = lookup_token(form.ctoken.borrow())?;
   let client = iad.ident;
   let mut ig = iad.gref.lock()?;
   ig.save_game_later();
index cb089fa458b675b640e860b2238bad6b43b88a7f..2de288e2a27b1bc13e82498e31ffa9c277df858c 100644 (file)
@@ -37,7 +37,7 @@ impl<'r> FromParam<'r> for CheckedResourceLeaf {
 
 #[derive(Serialize,Debug)]
 struct LoadingRenderContext<'r> {
-  ptoken : &'r str,
+  ptoken : &'r RawTokenVal,
 }
 #[get("/<ptoken>")]
 #[throws(OE)]
index ca143c26ca5647a7962128f55a6ef8bbc9bbabdd..3b933e81a24338f1d6be5f2de24af59086da7543 100644 (file)
@@ -12,6 +12,10 @@ const MAX_CLIENT_INACTIVITY : Duration = Duration::from_secs(200);
 
 const GAME_SAVE_LAG : Duration = Duration::from_millis(500);
 
+#[derive(Hash,Ord,PartialOrd,Eq,PartialEq,Serialize)]
+#[repr(transparent)]
+pub struct RawTokenVal(str);
+
 // ---------- public data structure ----------
 
 #[derive(Debug,Serialize,Deserialize)]
@@ -137,7 +141,7 @@ pub struct InstanceAccessDetails<Id> {
 
 #[derive(Clone,Debug)]
 pub struct InstanceAccess<'i, Id> {
-  pub raw_token : &'i str,
+  pub raw_token : &'i RawTokenVal,
   pub i : InstanceAccessDetails<Id>,
 }
 
@@ -183,8 +187,26 @@ const PRIVATE_Y : PrivateCaller = PrivateCaller(());
 
 // ========== implementations ==========
 
+/*
 impl Borrow<str> for RawToken {
   fn borrow(&self) -> &str { &self.0 }
+}*/
+
+impl RawTokenVal {
+  // str is [u8] with a funny hat on, so &str is pointer + byte count.
+  // nomicon says &SomeStruct([T]) is pointer plus number of elements.
+  // So &str and &SomeStruct(str) have the same layout
+  fn from_str(s: &str) -> &RawTokenVal { unsafe { mem::transmute(s) } }
+}
+
+impl Borrow<RawTokenVal> for RawToken {
+  fn borrow(&self) -> &RawTokenVal { RawTokenVal::from_str(&self.0) }
+}
+
+impl Debug for RawTokenVal {
+  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    crate::spec::implementation::raw_token_debug_as_str(&self.0, f)
+  }
 }
 
 // ---------- Main API for instance lifecycle ----------
@@ -789,7 +811,7 @@ impl RawToken {
   }
 }
 
-pub fn lookup_token<Id : AccessId>(s : &str)
+pub fn lookup_token<Id : AccessId>(s : &RawTokenVal)
       -> Result<InstanceAccessDetails<Id>, OE> {
   Id::global_tokens(PRIVATE_Y).read().unwrap().get(s).cloned()
     .ok_or(Id::ERROR)
@@ -802,7 +824,7 @@ impl<'r, Id> FromParam<'r> for InstanceAccess<'r, Id>
   #[throws(OE)]
   fn from_param(param: &'r RawStr) -> Self {
     let g = Id::global_tokens(PRIVATE_Y).read().unwrap();
-    let token = param.as_str();
+    let token = RawTokenVal::from_str(param.as_str());
     let i = g.get(token).ok_or(Id::ERROR)?;
     InstanceAccess { raw_token : token, i : i.clone() }
   }
index a65924c8bbe4e78393c75442a35ea64650fc1bb2..c13d75f913dad2740876303cd0ed7cfce108d664 100644 (file)
@@ -40,12 +40,12 @@ struct DataLoadPlayer {
 
 #[derive(Deserialize)]
 struct SessionForm {
-  ptoken : String,
+  ptoken : RawToken,
 }
 #[post("/_/session", format="json", data="<form>")]
 fn session(form : Json<SessionForm>) -> Result<Template,OE> {
   // make session in this game, log a message to other players
-  let iad = lookup_token(&form.ptoken)?;
+  let iad = lookup_token(form.ptoken.borrow())?;
   let player = iad.ident;
   let c = {
     let mut ig = iad.gref.lock()?;
index 26943187007e8f46ea573b6847bde3358b9e7508..d8a72cedcda546832c3886a2741fa0d2b77fa37c 100644 (file)
@@ -99,16 +99,20 @@ pub mod piece_specs {
 
 //---------- Implementation ----------
 
-mod implementation {
+pub mod implementation {
   use super::*;
   use crate::imports::*;
   type Insn = crate::commands::MgmtGameInstruction;
 
+  pub fn raw_token_debug_as_str(s: &str, f: &mut fmt::Formatter)
+                                -> fmt::Result {
+    let len = min(5, s.len() / 2);
+    write!(f, "{:?}...", &s[0..len])
+  }
+
   impl Debug for RawToken {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-      let s = &self.0;
-      let len = min(5, s.len() / 2);
-      write!(f, "{:?}...", &s[0..len])
+      raw_token_debug_as_str(&self.0, f)
     }
   }