From fe53a0d531b0feff877fcdf8328aaab5aeb72232 Mon Sep 17 00:00:00 2001 From: projectmoon Date: Sun, 10 Jan 2021 14:04:07 +0000 Subject: [PATCH] Create "character identifier" type for use in all API requests. Will replace the character_username and character_id values in all relevant requests. --- proto/cofd_api.proto | 11 +- src/frontend/_proto/cofd_api_pb.d.ts | 28 ++- src/frontend/_proto/cofd_api_pb.js | 251 ++++++++++++++++++++++----- src/models/proto.rs | 11 +- src/models/proto/cofd.rs | 15 ++ src/routes/api/cofd.rs | 6 +- 6 files changed, 275 insertions(+), 47 deletions(-) diff --git a/proto/cofd_api.proto b/proto/cofd_api.proto index 8116b4f..238167f 100644 --- a/proto/cofd_api.proto +++ b/proto/cofd_api.proto @@ -3,12 +3,19 @@ import "cofd.proto"; package models.proto.cofd.api; +message CharacterIdentifier { + string owner = 1; + int32 character_id = 2; +} + //Update basic information about a Chronicles of Darkness (or //derivative system) character sheet. This is a straight overwrite of //all basic information on the sheet. message UpdateBasicInfoRequest { - string owner = 1; - int32 character_id = 2; + CharacterIdentifier id = 1; + reserved 2; + // string owner = 1; + // int32 character_id = 2; string name = 3; string gender = 4; diff --git a/src/frontend/_proto/cofd_api_pb.d.ts b/src/frontend/_proto/cofd_api_pb.d.ts index 2360f96..36e9340 100644 --- a/src/frontend/_proto/cofd_api_pb.d.ts +++ b/src/frontend/_proto/cofd_api_pb.d.ts @@ -4,13 +4,36 @@ import * as jspb from "google-protobuf"; import * as cofd_pb from "./cofd_pb"; -export class UpdateBasicInfoRequest extends jspb.Message { +export class CharacterIdentifier extends jspb.Message { getOwner(): string; setOwner(value: string): void; getCharacterId(): number; setCharacterId(value: number): void; + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): CharacterIdentifier.AsObject; + static toObject(includeInstance: boolean, msg: CharacterIdentifier): CharacterIdentifier.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: CharacterIdentifier, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): CharacterIdentifier; + static deserializeBinaryFromReader(message: CharacterIdentifier, reader: jspb.BinaryReader): CharacterIdentifier; +} + +export namespace CharacterIdentifier { + export type AsObject = { + owner: string, + characterId: number, + } +} + +export class UpdateBasicInfoRequest extends jspb.Message { + hasId(): boolean; + clearId(): void; + getId(): CharacterIdentifier | undefined; + setId(value?: CharacterIdentifier): void; + getName(): string; setName(value: string): void; @@ -38,8 +61,7 @@ export class UpdateBasicInfoRequest extends jspb.Message { export namespace UpdateBasicInfoRequest { export type AsObject = { - owner: string, - characterId: number, + id?: CharacterIdentifier.AsObject, name: string, gender: string, concept: string, diff --git a/src/frontend/_proto/cofd_api_pb.js b/src/frontend/_proto/cofd_api_pb.js index c7cecbe..d4a29f1 100644 --- a/src/frontend/_proto/cofd_api_pb.js +++ b/src/frontend/_proto/cofd_api_pb.js @@ -18,12 +18,34 @@ var cofd_pb = require('./cofd_pb.js'); goog.object.extend(proto, cofd_pb); goog.exportSymbol('proto.models.proto.cofd.api.AddConditionRequest', null, global); goog.exportSymbol('proto.models.proto.cofd.api.ApiResult', null, global); +goog.exportSymbol('proto.models.proto.cofd.api.CharacterIdentifier', null, global); goog.exportSymbol('proto.models.proto.cofd.api.RemoveConditionRequest', null, global); goog.exportSymbol('proto.models.proto.cofd.api.UpdateAttributeRequest', null, global); goog.exportSymbol('proto.models.proto.cofd.api.UpdateBasicInfoRequest', null, global); goog.exportSymbol('proto.models.proto.cofd.api.UpdateSkillRequest', null, global); goog.exportSymbol('proto.models.proto.cofd.api.UpdateSkillSpecializationsRequest', null, global); goog.exportSymbol('proto.models.proto.cofd.api.UpdateSkillValueRequest', null, global); +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.models.proto.cofd.api.CharacterIdentifier = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.models.proto.cofd.api.CharacterIdentifier, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.models.proto.cofd.api.CharacterIdentifier.displayName = 'proto.models.proto.cofd.api.CharacterIdentifier'; +} /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a @@ -195,6 +217,166 @@ if (goog.DEBUG && !COMPILED) { +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.models.proto.cofd.api.CharacterIdentifier.prototype.toObject = function(opt_includeInstance) { + return proto.models.proto.cofd.api.CharacterIdentifier.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.models.proto.cofd.api.CharacterIdentifier} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.models.proto.cofd.api.CharacterIdentifier.toObject = function(includeInstance, msg) { + var f, obj = { + owner: jspb.Message.getFieldWithDefault(msg, 1, ""), + characterId: jspb.Message.getFieldWithDefault(msg, 2, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.models.proto.cofd.api.CharacterIdentifier} + */ +proto.models.proto.cofd.api.CharacterIdentifier.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.models.proto.cofd.api.CharacterIdentifier; + return proto.models.proto.cofd.api.CharacterIdentifier.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.models.proto.cofd.api.CharacterIdentifier} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.models.proto.cofd.api.CharacterIdentifier} + */ +proto.models.proto.cofd.api.CharacterIdentifier.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setOwner(value); + break; + case 2: + var value = /** @type {number} */ (reader.readInt32()); + msg.setCharacterId(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.models.proto.cofd.api.CharacterIdentifier.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.models.proto.cofd.api.CharacterIdentifier.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.models.proto.cofd.api.CharacterIdentifier} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.models.proto.cofd.api.CharacterIdentifier.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getOwner(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getCharacterId(); + if (f !== 0) { + writer.writeInt32( + 2, + f + ); + } +}; + + +/** + * optional string owner = 1; + * @return {string} + */ +proto.models.proto.cofd.api.CharacterIdentifier.prototype.getOwner = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.models.proto.cofd.api.CharacterIdentifier} returns this + */ +proto.models.proto.cofd.api.CharacterIdentifier.prototype.setOwner = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional int32 character_id = 2; + * @return {number} + */ +proto.models.proto.cofd.api.CharacterIdentifier.prototype.getCharacterId = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.models.proto.cofd.api.CharacterIdentifier} returns this + */ +proto.models.proto.cofd.api.CharacterIdentifier.prototype.setCharacterId = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + + + + if (jspb.Message.GENERATE_TO_OBJECT) { /** * Creates an object representation of this proto. @@ -224,8 +406,7 @@ proto.models.proto.cofd.api.UpdateBasicInfoRequest.prototype.toObject = function */ proto.models.proto.cofd.api.UpdateBasicInfoRequest.toObject = function(includeInstance, msg) { var f, obj = { - owner: jspb.Message.getFieldWithDefault(msg, 1, ""), - characterId: jspb.Message.getFieldWithDefault(msg, 2, 0), + id: (f = msg.getId()) && proto.models.proto.cofd.api.CharacterIdentifier.toObject(includeInstance, f), name: jspb.Message.getFieldWithDefault(msg, 3, ""), gender: jspb.Message.getFieldWithDefault(msg, 4, ""), concept: jspb.Message.getFieldWithDefault(msg, 5, ""), @@ -268,12 +449,9 @@ proto.models.proto.cofd.api.UpdateBasicInfoRequest.deserializeBinaryFromReader = var field = reader.getFieldNumber(); switch (field) { case 1: - var value = /** @type {string} */ (reader.readString()); - msg.setOwner(value); - break; - case 2: - var value = /** @type {number} */ (reader.readInt32()); - msg.setCharacterId(value); + var value = new proto.models.proto.cofd.api.CharacterIdentifier; + reader.readMessage(value,proto.models.proto.cofd.api.CharacterIdentifier.deserializeBinaryFromReader); + msg.setId(value); break; case 3: var value = /** @type {string} */ (reader.readString()); @@ -324,18 +502,12 @@ proto.models.proto.cofd.api.UpdateBasicInfoRequest.prototype.serializeBinary = f */ proto.models.proto.cofd.api.UpdateBasicInfoRequest.serializeBinaryToWriter = function(message, writer) { var f = undefined; - f = message.getOwner(); - if (f.length > 0) { - writer.writeString( + f = message.getId(); + if (f != null) { + writer.writeMessage( 1, - f - ); - } - f = message.getCharacterId(); - if (f !== 0) { - writer.writeInt32( - 2, - f + f, + proto.models.proto.cofd.api.CharacterIdentifier.serializeBinaryToWriter ); } f = message.getName(); @@ -377,38 +549,39 @@ proto.models.proto.cofd.api.UpdateBasicInfoRequest.serializeBinaryToWriter = fun /** - * optional string owner = 1; - * @return {string} + * optional CharacterIdentifier id = 1; + * @return {?proto.models.proto.cofd.api.CharacterIdentifier} */ -proto.models.proto.cofd.api.UpdateBasicInfoRequest.prototype.getOwner = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +proto.models.proto.cofd.api.UpdateBasicInfoRequest.prototype.getId = function() { + return /** @type{?proto.models.proto.cofd.api.CharacterIdentifier} */ ( + jspb.Message.getWrapperField(this, proto.models.proto.cofd.api.CharacterIdentifier, 1)); }; /** - * @param {string} value + * @param {?proto.models.proto.cofd.api.CharacterIdentifier|undefined} value + * @return {!proto.models.proto.cofd.api.UpdateBasicInfoRequest} returns this +*/ +proto.models.proto.cofd.api.UpdateBasicInfoRequest.prototype.setId = function(value) { + return jspb.Message.setWrapperField(this, 1, value); +}; + + +/** + * Clears the message field making it undefined. * @return {!proto.models.proto.cofd.api.UpdateBasicInfoRequest} returns this */ -proto.models.proto.cofd.api.UpdateBasicInfoRequest.prototype.setOwner = function(value) { - return jspb.Message.setProto3StringField(this, 1, value); +proto.models.proto.cofd.api.UpdateBasicInfoRequest.prototype.clearId = function() { + return this.setId(undefined); }; /** - * optional int32 character_id = 2; - * @return {number} + * Returns whether this field is set. + * @return {boolean} */ -proto.models.proto.cofd.api.UpdateBasicInfoRequest.prototype.getCharacterId = function() { - return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); -}; - - -/** - * @param {number} value - * @return {!proto.models.proto.cofd.api.UpdateBasicInfoRequest} returns this - */ -proto.models.proto.cofd.api.UpdateBasicInfoRequest.prototype.setCharacterId = function(value) { - return jspb.Message.setProto3IntField(this, 2, value); +proto.models.proto.cofd.api.UpdateBasicInfoRequest.prototype.hasId = function() { + return jspb.Message.getField(this, 1) != null; }; diff --git a/src/models/proto.rs b/src/models/proto.rs index c998348..0d967bf 100644 --- a/src/models/proto.rs +++ b/src/models/proto.rs @@ -7,7 +7,7 @@ use rocket::response::status; use rocket::response::{self, Responder, Response}; use std::default::Default; use std::io::Cursor; -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; pub mod cofd; @@ -79,3 +79,12 @@ where &self.0 } } + +impl DerefMut for Proto +where + T: prost::Message + Default, +{ + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/src/models/proto/cofd.rs b/src/models/proto/cofd.rs index 4e1e023..304561a 100644 --- a/src/models/proto/cofd.rs +++ b/src/models/proto/cofd.rs @@ -14,6 +14,21 @@ pub mod api { //include!(concat!(env!("OUT_DIR"), "/models.proto.cofd.api.rs")); tonic::include_proto!("models.proto.cofd.api"); + /// Trait to extract CharacterIdentifier while avoiding clone. The + /// character identifier is extracted out of the Option, leaving + /// None in its place. + pub trait DefaultCharacterIdentifier { + /// Extract the CharacterIdentifier from the containing type, + /// leaving behind a default value. + fn or_default(&mut self) -> CharacterIdentifier; + } + + impl DefaultCharacterIdentifier for Option { + fn or_default(&mut self) -> CharacterIdentifier { + self.take().unwrap_or_default() + } + } + /// Helpers for the ApiResult class. impl ApiResult { pub fn success() -> Self { diff --git a/src/routes/api/cofd.rs b/src/routes/api/cofd.rs index 10a1c1f..e95a4d1 100644 --- a/src/routes/api/cofd.rs +++ b/src/routes/api/cofd.rs @@ -2,6 +2,7 @@ use super::load_character; use crate::db::{Dao, TenebrousDbConn}; use crate::errors::Error; use crate::models::characters::Character; +use crate::models::proto::cofd::api::DefaultCharacterIdentifier; use crate::models::proto::cofd::cofd_sheet::Skill; use crate::models::proto::cofd::*; use crate::models::proto::{cofd::api::*, cofd::*, Proto}; @@ -39,11 +40,12 @@ fn find_skill<'a>(sheet: &'a mut CofdSheet, skill_name: &'a str) -> Option<&'a m #[post("/rpc/cofd/update_basic_info", data = "")] pub(super) async fn update_basic_info<'a>( - req: Proto, + mut req: Proto, conn: TenebrousDbConn<'_>, logged_in_user: Option<&User>, ) -> Result, Error> { - let mut character = load_character(&conn, logged_in_user, &req.owner, req.character_id).await?; + let id = req.id.or_default(); + let mut character = load_character(&conn, logged_in_user, &id.owner, id.character_id).await?; let mut sheet: CofdSheet = character.try_deserialize()?; sheet.name = req.name.clone();