chiark / gitweb /
api: Skeleton support for loose ops
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 14 Jul 2021 15:03:44 +0000 (16:03 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Wed, 14 Jul 2021 15:03:44 +0000 (16:03 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/api.rs
src/error.rs

index 988d603a4bb7d11288a23b045b664308cd128003..41cc8380d1ee5e83184c984bab3cd6c7cad1cf72 100644 (file)
@@ -32,9 +32,13 @@ struct ApiPiece<O:op::Complex> {
   piece: VisiblePieceId,
   gen: Generation,
   cseq: ClientSequence,
+  #[serde(default)] loose: bool,
   op: O,
 }
 
+#[derive(Debug)]
+pub struct ContinueDespiteConflict;
+
 mod op {
   use super::*;
 
@@ -45,6 +49,11 @@ mod op {
         throw!(Ia::PieceHeld)
       }
     }
+
+    fn conflict_loose_check(&self, _gpc: &GPiece)
+        -> Result<ContinueDespiteConflict, ApiPieceOpError> {
+      throw!(Fatal::BadLoose)
+    }
   }
 
   pub trait Simple: Debug { 
@@ -76,7 +85,7 @@ impl From<&FatalErrorResponse> for rocket::http::Status {
       ServerFailure(_) => Status::InternalServerError,
       NoClient | NoPlayer(_) | GameBeingDestroyed(_)
         => Status::NotFound,
-      BadJSON(_)
+      BadJSON(_) | BadLoose
         => Status::BadRequest,
     }
   }
@@ -131,7 +140,10 @@ fn api_piece_op<O: op::Complex>(form: Json<ApiPiece<O>>)
 
     debug!("client={:?} pc.lastclient={:?} pc.gen_before={:?} pc.gen={:?} q_gen={:?} u_gen={:?}", &client, &gpc.lastclient, &gpc.gen_before_lastclient, &gpc.gen, &q_gen, &u_gen);
 
-    if u_gen > q_gen { throw!(Inapplicable::Conflict) }
+    if u_gen > q_gen {
+      if ! form.loose { throw!(Inapplicable::Conflict); }
+      let ContinueDespiteConflict = form.op.conflict_loose_check(&gpc)?;
+    }
     trace_dbg!("form.op", player, piece, &form.op, &gpc);
     form.op.check_held(gpc,player)?;
     let update =
index 695fd1eac2ac203eda2a13c489543aa155dc425e..035ed65f19974d34c55a16c7b854579c80ea9e83 100644 (file)
@@ -16,6 +16,8 @@ pub enum Fatal { // Includes _bogus_ client updates, see PROTOCOL.md
   ServerFailure(#[from] InternalError),
   #[error("JSON deserialisation error: {0}")]
   BadJSON(serde_json::Error),
+  #[error("Malformed command - loose not allowed for this op")]
+  BadLoose,
 }
 
 #[derive(Error,Debug)]