diff --git a/common/build.rs b/common/build.rs index 41b5b4b..da17cd4 100644 --- a/common/build.rs +++ b/common/build.rs @@ -24,6 +24,14 @@ fn main() -> Result<(), Box> { ".komp_ac.table_validation.PatternRule", "#[derive(serde::Serialize, serde::Deserialize)]", ) + .type_attribute( + ".komp_ac.table_validation.PatternPosition", + "#[derive(serde::Serialize, serde::Deserialize)]", + ) + .type_attribute( + ".komp_ac.table_validation.CharacterConstraint", + "#[derive(serde::Serialize, serde::Deserialize)]", + ) .type_attribute( ".komp_ac.table_validation.PatternRules", "#[derive(serde::Serialize, serde::Deserialize)]", @@ -32,6 +40,14 @@ fn main() -> Result<(), Box> { ".komp_ac.table_validation.CustomFormatter", "#[derive(serde::Serialize, serde::Deserialize)]", ) + .type_attribute( + ".komp_ac.table_validation.FormatterOption", + "#[derive(serde::Serialize, serde::Deserialize)]", + ) + .type_attribute( + ".komp_ac.table_validation.AllowedValues", + "#[derive(serde::Serialize, serde::Deserialize)]", + ) .type_attribute( ".komp_ac.table_validation.UpdateFieldValidationRequest", "#[derive(serde::Serialize, serde::Deserialize)]", @@ -40,11 +56,27 @@ fn main() -> Result<(), Box> { ".komp_ac.table_validation.UpdateFieldValidationResponse", "#[derive(serde::Serialize, serde::Deserialize)]", ) + .type_attribute( + ".komp_ac.table_validation.ReplaceTableValidationRequest", + "#[derive(serde::Serialize, serde::Deserialize)]", + ) + .type_attribute( + ".komp_ac.table_validation.ReplaceTableValidationResponse", + "#[derive(serde::Serialize, serde::Deserialize)]", + ) // Enum -> readable strings in JSON ("BYTES", "DISPLAY_WIDTH") .type_attribute( ".komp_ac.table_validation.CountMode", "#[derive(serde::Serialize, serde::Deserialize)] #[serde(rename_all = \"SCREAMING_SNAKE_CASE\")]", ) + .type_attribute( + ".komp_ac.table_validation.PatternPositionKind", + "#[derive(serde::Serialize, serde::Deserialize)] #[serde(rename_all = \"SCREAMING_SNAKE_CASE\")]", + ) + .type_attribute( + ".komp_ac.table_validation.CharacterConstraintKind", + "#[derive(serde::Serialize, serde::Deserialize)] #[serde(rename_all = \"SCREAMING_SNAKE_CASE\")]", + ) .type_attribute( ".komp_ac.table_definition.ColumnDefinition", "#[derive(serde::Serialize, serde::Deserialize)]", diff --git a/common/proto/table_validation.proto b/common/proto/table_validation.proto index 1356123..ed13448 100644 --- a/common/proto/table_validation.proto +++ b/common/proto/table_validation.proto @@ -2,31 +2,55 @@ syntax = "proto3"; package komp_ac.table_validation; +// This proto is the canonical server-side storage and distribution contract for +// client validation configuration. +// +// Design goals: +// - The server stores the entire field validation definition in one structured payload. +// - Clients fetch the validation rules for a table in one batch and map them to +// their local validation/runtime system (for example canvas). +// - Common validation must be represented as typed data, not as string mini-languages. +// +// Important split: +// - limits / pattern / allowed_values / required are validation rules. +// - mask / formatter are presentation and input-shaping metadata for clients. + // Request validation rules for a table message GetTableValidationRequest { string profileName = 1; string tableName = 2; } -// Response with field-level validations; if a field is omitted, -// no validation is applied (default unspecified). +// Response with field-level validations for the whole table. +// If a field is omitted, no validation configuration exists for that field. message TableValidationResponse { repeated FieldValidation fields = 1; } -// Field-level validation (extensible for future kinds) +// Field-level validation definition stored on the server and distributed to clients. message FieldValidation { // MUST match your frontend FormState.dataKey for the column string dataKey = 1; - // Current: only CharacterLimits. More rules can be added later. + // Validation 1: length and counting rules. CharacterLimits limits = 10; - // Future expansion: - PatternRules pattern = 11; // Validation 2 - optional CustomFormatter formatter = 14; // Validation 4 – custom formatting logic + + // Validation 2: position-based character constraints. + PatternRules pattern = 11; + + // Exact-value whitelist. + AllowedValues allowed_values = 12; + + // Client-side hint that this field participates in external/asynchronous validation UI. + bool external_validation_enabled = 13; + + // Client-side formatter metadata. This is intentionally data-only, not executable code. + optional CustomFormatter formatter = 14; + + // Client-side display mask metadata. The server stores raw data without mask literals. DisplayMask mask = 3; - // ExternalValidation external = 13; - // CustomFormatter formatter = 14; + + // Field must be provided / treated as required by clients and server enforcement layers. bool required = 4; } @@ -38,7 +62,8 @@ enum CountMode { DISPLAY_WIDTH = 3; } -// Character limit validation (Validation 1) +// Character limit validation (Validation 1). +// These rules map directly to canvas CharacterLimits. message CharacterLimits { // When zero, the field is considered "not set". If both min/max are zero, // the server should avoid sending this FieldValidation (no validation). @@ -51,39 +76,91 @@ message CharacterLimits { CountMode countMode = 4; // defaults to CHARS if unspecified } -// Mask for pretty display +// Mask for pretty display only. +// +// This is not a validation rule by itself. It exists so clients can render and +// navigate masked input while still storing raw values server-side. message DisplayMask { string pattern = 1; // e.g., "(###) ###-####" or "####-##-##" string input_char = 2; // e.g., "#" optional string template_char = 3; // e.g., "_" } -// One position‑based validation rule, similar to CharacterFilter + PositionRange -message PatternRule { - // Range descriptor: how far the rule applies - // Examples: - // - "0" → Single position 0 - // - "0-3" → Range 0..3 inclusive - // - "from:5" → From position 5 onward - // - "0,2,5" → Multiple discrete positions - string range = 1; - - // Character filter type, case‑insensitive keywords: - // "ALPHABETIC", "NUMERIC", "ALPHANUMERIC", - // "ONEOF()", "EXACT(:)", "CUSTOM()" - string filter = 2; +// Which positions a pattern rule applies to. +// This exists instead of a string syntax like "0-3" so the server can validate +// the structure directly and clients do not need to parse a DSL. +message PatternPosition { + PatternPositionKind kind = 1; + uint32 single = 2; + uint32 start = 3; + uint32 end = 4; + repeated uint32 positions = 5; } +enum PatternPositionKind { + PATTERN_POSITION_KIND_UNSPECIFIED = 0; + PATTERN_POSITION_SINGLE = 1; + PATTERN_POSITION_RANGE = 2; + PATTERN_POSITION_FROM = 3; + PATTERN_POSITION_MULTIPLE = 4; +} + +// What type of character constraint a pattern rule applies. +// This mirrors the typed character filters used by canvas. +message CharacterConstraint { + CharacterConstraintKind kind = 1; + + // Used when kind == CHARACTER_CONSTRAINT_EXACT. + optional string exact = 2; + + // Used when kind == CHARACTER_CONSTRAINT_ONE_OF. + repeated string one_of = 3; + + // Used when kind == CHARACTER_CONSTRAINT_REGEX. + optional string regex = 4; +} + +enum CharacterConstraintKind { + CHARACTER_CONSTRAINT_KIND_UNSPECIFIED = 0; + CHARACTER_CONSTRAINT_ALPHABETIC = 1; + CHARACTER_CONSTRAINT_NUMERIC = 2; + CHARACTER_CONSTRAINT_ALPHANUMERIC = 3; + CHARACTER_CONSTRAINT_EXACT = 4; + CHARACTER_CONSTRAINT_ONE_OF = 5; + CHARACTER_CONSTRAINT_REGEX = 6; +} + +// One position-based validation rule, similar to canvas PositionFilter. +message PatternRule { + PatternPosition position = 1; + CharacterConstraint constraint = 2; +} + +// Client-side formatter metadata. +// The formatter "type" is intended to be resolved by a client-side formatter registry. message CustomFormatter { // Formatter type identifier; handled client‑side. // Examples: "PSCFormatter", "PhoneFormatter", "CreditCardFormatter", "DateFormatter" string type = 1; - // Optional free‑text note or parameters (e.g. locale, pattern) - optional string description = 2; + repeated FormatterOption options = 2; + optional string description = 3; } -// Collection of pattern rules for one field +message FormatterOption { + string key = 1; + string value = 2; +} + +// Exact-value whitelist configuration. +// This maps to canvas AllowedValues semantics. +message AllowedValues { + repeated string values = 1; + bool allow_empty = 2; + bool case_insensitive = 3; +} + +// Collection of pattern rules for one field. message PatternRules { // All rules that make up the validation logic repeated PatternRule rules = 1; @@ -92,11 +169,15 @@ message PatternRules { optional string description = 2; } -// Service to fetch validations for a table +// Service for storing and fetching field-validation definitions. service TableValidationService { rpc GetTableValidation(GetTableValidationRequest) returns (TableValidationResponse); + // Upsert a single field validation definition. rpc UpdateFieldValidation(UpdateFieldValidationRequest) returns (UpdateFieldValidationResponse); + + // Replace the full validation definition set for a table in one transaction. + rpc ReplaceTableValidation(ReplaceTableValidationRequest) returns (ReplaceTableValidationResponse); } message UpdateFieldValidationRequest { @@ -110,3 +191,16 @@ message UpdateFieldValidationResponse { bool success = 1; string message = 2; } + +message ReplaceTableValidationRequest { + string profileName = 1; + string tableName = 2; + + // Full replacement set. Fields omitted here are removed from the stored config. + repeated FieldValidation fields = 3; +} + +message ReplaceTableValidationResponse { + bool success = 1; + string message = 2; +} diff --git a/common/src/proto/descriptor.bin b/common/src/proto/descriptor.bin index 8be89c3..73620a7 100644 Binary files a/common/src/proto/descriptor.bin and b/common/src/proto/descriptor.bin differ diff --git a/common/src/proto/komp_ac.table_validation.rs b/common/src/proto/komp_ac.table_validation.rs index befe58c..bbf3bce 100644 --- a/common/src/proto/komp_ac.table_validation.rs +++ b/common/src/proto/komp_ac.table_validation.rs @@ -7,40 +7,45 @@ pub struct GetTableValidationRequest { #[prost(string, tag = "2")] pub table_name: ::prost::alloc::string::String, } -/// Response with field-level validations; if a field is omitted, -/// no validation is applied (default unspecified). +/// Response with field-level validations for the whole table. +/// If a field is omitted, no validation configuration exists for that field. #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TableValidationResponse { #[prost(message, repeated, tag = "1")] pub fields: ::prost::alloc::vec::Vec, } -/// Field-level validation (extensible for future kinds) +/// Field-level validation definition stored on the server and distributed to clients. #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FieldValidation { /// MUST match your frontend FormState.dataKey for the column #[prost(string, tag = "1")] pub data_key: ::prost::alloc::string::String, - /// Current: only CharacterLimits. More rules can be added later. + /// Validation 1: length and counting rules. #[prost(message, optional, tag = "10")] pub limits: ::core::option::Option, - /// Future expansion: - /// - /// Validation 2 + /// Validation 2: position-based character constraints. #[prost(message, optional, tag = "11")] pub pattern: ::core::option::Option, - /// Validation 4 – custom formatting logic + /// Exact-value whitelist. + #[prost(message, optional, tag = "12")] + pub allowed_values: ::core::option::Option, + /// Client-side hint that this field participates in external/asynchronous validation UI. + #[prost(bool, tag = "13")] + pub external_validation_enabled: bool, + /// Client-side formatter metadata. This is intentionally data-only, not executable code. #[prost(message, optional, tag = "14")] pub formatter: ::core::option::Option, + /// Client-side display mask metadata. The server stores raw data without mask literals. #[prost(message, optional, tag = "3")] pub mask: ::core::option::Option, - /// ExternalValidation external = 13; - /// CustomFormatter formatter = 14; + /// Field must be provided / treated as required by clients and server enforcement layers. #[prost(bool, tag = "4")] pub required: bool, } -/// Character limit validation (Validation 1) +/// Character limit validation (Validation 1). +/// These rules map directly to canvas CharacterLimits. #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, Copy, PartialEq, ::prost::Message)] pub struct CharacterLimits { @@ -57,7 +62,10 @@ pub struct CharacterLimits { #[prost(enumeration = "CountMode", tag = "4")] pub count_mode: i32, } -/// Mask for pretty display +/// Mask for pretty display only. +/// +/// This is not a validation rule by itself. It exists so clients can render and +/// navigate masked input while still storing raw values server-side. #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DisplayMask { @@ -71,24 +79,51 @@ pub struct DisplayMask { #[prost(string, optional, tag = "3")] pub template_char: ::core::option::Option<::prost::alloc::string::String>, } -/// One position‑based validation rule, similar to CharacterFilter + PositionRange +/// Which positions a pattern rule applies to. +/// This exists instead of a string syntax like "0-3" so the server can validate +/// the structure directly and clients do not need to parse a DSL. +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct PatternPosition { + #[prost(enumeration = "PatternPositionKind", tag = "1")] + pub kind: i32, + #[prost(uint32, tag = "2")] + pub single: u32, + #[prost(uint32, tag = "3")] + pub start: u32, + #[prost(uint32, tag = "4")] + pub end: u32, + #[prost(uint32, repeated, tag = "5")] + pub positions: ::prost::alloc::vec::Vec, +} +/// What type of character constraint a pattern rule applies. +/// This mirrors the typed character filters used by canvas. +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CharacterConstraint { + #[prost(enumeration = "CharacterConstraintKind", tag = "1")] + pub kind: i32, + /// Used when kind == CHARACTER_CONSTRAINT_EXACT. + #[prost(string, optional, tag = "2")] + pub exact: ::core::option::Option<::prost::alloc::string::String>, + /// Used when kind == CHARACTER_CONSTRAINT_ONE_OF. + #[prost(string, repeated, tag = "3")] + pub one_of: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + /// Used when kind == CHARACTER_CONSTRAINT_REGEX. + #[prost(string, optional, tag = "4")] + pub regex: ::core::option::Option<::prost::alloc::string::String>, +} +/// One position-based validation rule, similar to canvas PositionFilter. #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PatternRule { - /// Range descriptor: how far the rule applies - /// Examples: - /// - "0" → Single position 0 - /// - "0-3" → Range 0..3 inclusive - /// - "from:5" → From position 5 onward - /// - "0,2,5" → Multiple discrete positions - #[prost(string, tag = "1")] - pub range: ::prost::alloc::string::String, - /// Character filter type, case‑insensitive keywords: - /// "ALPHABETIC", "NUMERIC", "ALPHANUMERIC", - /// "ONEOF()", "EXACT(:)", "CUSTOM()" - #[prost(string, tag = "2")] - pub filter: ::prost::alloc::string::String, + #[prost(message, optional, tag = "1")] + pub position: ::core::option::Option, + #[prost(message, optional, tag = "2")] + pub constraint: ::core::option::Option, } +/// Client-side formatter metadata. +/// The formatter "type" is intended to be resolved by a client-side formatter registry. #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CustomFormatter { @@ -96,11 +131,32 @@ pub struct CustomFormatter { /// Examples: "PSCFormatter", "PhoneFormatter", "CreditCardFormatter", "DateFormatter" #[prost(string, tag = "1")] pub r#type: ::prost::alloc::string::String, - /// Optional free‑text note or parameters (e.g. locale, pattern) - #[prost(string, optional, tag = "2")] + #[prost(message, repeated, tag = "2")] + pub options: ::prost::alloc::vec::Vec, + #[prost(string, optional, tag = "3")] pub description: ::core::option::Option<::prost::alloc::string::String>, } -/// Collection of pattern rules for one field +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct FormatterOption { + #[prost(string, tag = "1")] + pub key: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub value: ::prost::alloc::string::String, +} +/// Exact-value whitelist configuration. +/// This maps to canvas AllowedValues semantics. +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct AllowedValues { + #[prost(string, repeated, tag = "1")] + pub values: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(bool, tag = "2")] + pub allow_empty: bool, + #[prost(bool, tag = "3")] + pub case_insensitive: bool, +} +/// Collection of pattern rules for one field. #[derive(serde::Serialize, serde::Deserialize)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PatternRules { @@ -131,6 +187,25 @@ pub struct UpdateFieldValidationResponse { #[prost(string, tag = "2")] pub message: ::prost::alloc::string::String, } +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ReplaceTableValidationRequest { + #[prost(string, tag = "1")] + pub profile_name: ::prost::alloc::string::String, + #[prost(string, tag = "2")] + pub table_name: ::prost::alloc::string::String, + /// Full replacement set. Fields omitted here are removed from the stored config. + #[prost(message, repeated, tag = "3")] + pub fields: ::prost::alloc::vec::Vec, +} +#[derive(serde::Serialize, serde::Deserialize)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ReplaceTableValidationResponse { + #[prost(bool, tag = "1")] + pub success: bool, + #[prost(string, tag = "2")] + pub message: ::prost::alloc::string::String, +} /// Character length counting mode #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] @@ -167,6 +242,90 @@ impl CountMode { } } } +#[derive(serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum PatternPositionKind { + Unspecified = 0, + PatternPositionSingle = 1, + PatternPositionRange = 2, + PatternPositionFrom = 3, + PatternPositionMultiple = 4, +} +impl PatternPositionKind { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "PATTERN_POSITION_KIND_UNSPECIFIED", + Self::PatternPositionSingle => "PATTERN_POSITION_SINGLE", + Self::PatternPositionRange => "PATTERN_POSITION_RANGE", + Self::PatternPositionFrom => "PATTERN_POSITION_FROM", + Self::PatternPositionMultiple => "PATTERN_POSITION_MULTIPLE", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "PATTERN_POSITION_KIND_UNSPECIFIED" => Some(Self::Unspecified), + "PATTERN_POSITION_SINGLE" => Some(Self::PatternPositionSingle), + "PATTERN_POSITION_RANGE" => Some(Self::PatternPositionRange), + "PATTERN_POSITION_FROM" => Some(Self::PatternPositionFrom), + "PATTERN_POSITION_MULTIPLE" => Some(Self::PatternPositionMultiple), + _ => None, + } + } +} +#[derive(serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] +#[repr(i32)] +pub enum CharacterConstraintKind { + Unspecified = 0, + CharacterConstraintAlphabetic = 1, + CharacterConstraintNumeric = 2, + CharacterConstraintAlphanumeric = 3, + CharacterConstraintExact = 4, + CharacterConstraintOneOf = 5, + CharacterConstraintRegex = 6, +} +impl CharacterConstraintKind { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + Self::Unspecified => "CHARACTER_CONSTRAINT_KIND_UNSPECIFIED", + Self::CharacterConstraintAlphabetic => "CHARACTER_CONSTRAINT_ALPHABETIC", + Self::CharacterConstraintNumeric => "CHARACTER_CONSTRAINT_NUMERIC", + Self::CharacterConstraintAlphanumeric => "CHARACTER_CONSTRAINT_ALPHANUMERIC", + Self::CharacterConstraintExact => "CHARACTER_CONSTRAINT_EXACT", + Self::CharacterConstraintOneOf => "CHARACTER_CONSTRAINT_ONE_OF", + Self::CharacterConstraintRegex => "CHARACTER_CONSTRAINT_REGEX", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "CHARACTER_CONSTRAINT_KIND_UNSPECIFIED" => Some(Self::Unspecified), + "CHARACTER_CONSTRAINT_ALPHABETIC" => { + Some(Self::CharacterConstraintAlphabetic) + } + "CHARACTER_CONSTRAINT_NUMERIC" => Some(Self::CharacterConstraintNumeric), + "CHARACTER_CONSTRAINT_ALPHANUMERIC" => { + Some(Self::CharacterConstraintAlphanumeric) + } + "CHARACTER_CONSTRAINT_EXACT" => Some(Self::CharacterConstraintExact), + "CHARACTER_CONSTRAINT_ONE_OF" => Some(Self::CharacterConstraintOneOf), + "CHARACTER_CONSTRAINT_REGEX" => Some(Self::CharacterConstraintRegex), + _ => None, + } + } +} /// Generated client implementations. pub mod table_validation_service_client { #![allow( @@ -178,7 +337,7 @@ pub mod table_validation_service_client { )] use tonic::codegen::*; use tonic::codegen::http::Uri; - /// Service to fetch validations for a table + /// Service for storing and fetching field-validation definitions. #[derive(Debug, Clone)] pub struct TableValidationServiceClient { inner: tonic::client::Grpc, @@ -290,6 +449,7 @@ pub mod table_validation_service_client { ); self.inner.unary(req, path, codec).await } + /// Upsert a single field validation definition. pub async fn update_field_validation( &mut self, request: impl tonic::IntoRequest, @@ -319,6 +479,36 @@ pub mod table_validation_service_client { ); self.inner.unary(req, path, codec).await } + /// Replace the full validation definition set for a table in one transaction. + pub async fn replace_table_validation( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::unknown( + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/komp_ac.table_validation.TableValidationService/ReplaceTableValidation", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "komp_ac.table_validation.TableValidationService", + "ReplaceTableValidation", + ), + ); + self.inner.unary(req, path, codec).await + } } } /// Generated server implementations. @@ -341,6 +531,7 @@ pub mod table_validation_service_server { tonic::Response, tonic::Status, >; + /// Upsert a single field validation definition. async fn update_field_validation( &self, request: tonic::Request, @@ -348,8 +539,16 @@ pub mod table_validation_service_server { tonic::Response, tonic::Status, >; + /// Replace the full validation definition set for a table in one transaction. + async fn replace_table_validation( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + >; } - /// Service to fetch validations for a table + /// Service for storing and fetching field-validation definitions. #[derive(Debug)] pub struct TableValidationServiceServer { inner: Arc, @@ -527,6 +726,57 @@ pub mod table_validation_service_server { }; Box::pin(fut) } + "/komp_ac.table_validation.TableValidationService/ReplaceTableValidation" => { + #[allow(non_camel_case_types)] + struct ReplaceTableValidationSvc( + pub Arc, + ); + impl< + T: TableValidationService, + > tonic::server::UnaryService + for ReplaceTableValidationSvc { + type Response = super::ReplaceTableValidationResponse; + type Future = BoxFuture< + tonic::Response, + tonic::Status, + >; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::replace_table_validation( + &inner, + request, + ) + .await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = ReplaceTableValidationSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } _ => { Box::pin(async move { let mut response = http::Response::new( diff --git a/server b/server index 8dbe9cc..8a84218 160000 --- a/server +++ b/server @@ -1 +1 @@ -Subproject commit 8dbe9cc14c6834ff12195c5a7958f2a593f8cc81 +Subproject commit 8a84218de35d7365a4231ec0c35d768b75ee3ed3