feat(protocol): negotiate display and native input
This commit is contained in:
+143
-23
@@ -13,7 +13,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
const SchemaSHA256 = "a86cbdaf2cfb884e3d98467968007e731ca55c6f6eb6dbd5cd6b95e062a9b058"
|
||||
const SchemaSHA256 = "b2bb0a8ac8ef56dbc0e1443eeb5b3028be9e71ec2f5fd8e73928d71b7cd9340c"
|
||||
const ProtocolVersion = "1.0.0"
|
||||
const CurrentWireVersion = "1"
|
||||
const NMinus1WireVersion = "0"
|
||||
@@ -50,21 +50,23 @@ type AssignedDesktop struct {
|
||||
}
|
||||
|
||||
type BrokerSession struct {
|
||||
ID string `json:"id"`
|
||||
PrincipalID string `json:"principal_id"`
|
||||
PoolID string `json:"pool_id"`
|
||||
AssignmentID string `json:"assignment_id,omitempty"`
|
||||
State string `json:"state"`
|
||||
PolicySnapshot AllocationPolicy `json:"policy_snapshot"`
|
||||
ReconnectDeadline string `json:"reconnect_deadline,omitempty"`
|
||||
Outcome string `json:"outcome,omitempty"`
|
||||
FailureCode string `json:"failure_code,omitempty"`
|
||||
CleanupState string `json:"cleanup_state"`
|
||||
IdempotencyKey string `json:"idempotency_key"`
|
||||
CorrelationID string `json:"correlation_id"`
|
||||
RequestedAt string `json:"requested_at"`
|
||||
EndedAt string `json:"ended_at,omitempty"`
|
||||
Version int64 `json:"version"`
|
||||
ID string `json:"id"`
|
||||
PrincipalID string `json:"principal_id"`
|
||||
PoolID string `json:"pool_id"`
|
||||
AssignmentID string `json:"assignment_id,omitempty"`
|
||||
State string `json:"state"`
|
||||
PolicySnapshot AllocationPolicy `json:"policy_snapshot"`
|
||||
ReconnectDeadline string `json:"reconnect_deadline,omitempty"`
|
||||
Outcome string `json:"outcome,omitempty"`
|
||||
FailureCode string `json:"failure_code,omitempty"`
|
||||
CleanupState string `json:"cleanup_state"`
|
||||
IdempotencyKey string `json:"idempotency_key"`
|
||||
CorrelationID string `json:"correlation_id"`
|
||||
RequestedAt string `json:"requested_at"`
|
||||
EndedAt string `json:"ended_at,omitempty"`
|
||||
Version int64 `json:"version"`
|
||||
RequestedDisplayMode *DisplayMode `json:"requested_display_mode,omitempty"`
|
||||
EffectiveDisplayMode *DisplayMode `json:"effective_display_mode,omitempty"`
|
||||
}
|
||||
|
||||
type CapabilityProfile struct {
|
||||
@@ -134,6 +136,12 @@ type DeviceRegistrationRequest struct {
|
||||
PublicKey string `json:"public_key"`
|
||||
}
|
||||
|
||||
type DisplayMode struct {
|
||||
ResolutionWidth int64 `json:"resolution_width"`
|
||||
ResolutionHeight int64 `json:"resolution_height"`
|
||||
Fps int64 `json:"fps"`
|
||||
}
|
||||
|
||||
type EntitledPool struct {
|
||||
PoolID string `json:"pool_id"`
|
||||
Name string `json:"name"`
|
||||
@@ -263,8 +271,9 @@ type ManifestGateway struct {
|
||||
}
|
||||
|
||||
type ManifestProfile struct {
|
||||
ID string `json:"id"`
|
||||
Bounds ManifestBounds `json:"bounds"`
|
||||
ID string `json:"id"`
|
||||
Bounds ManifestBounds `json:"bounds"`
|
||||
DisplayMode *DisplayMode `json:"display_mode,omitempty"`
|
||||
}
|
||||
|
||||
type ManifestTunnel struct {
|
||||
@@ -383,11 +392,12 @@ type SessionAuthority struct {
|
||||
}
|
||||
|
||||
type SessionRequest struct {
|
||||
ClientDeviceID string `json:"client_device_id"`
|
||||
DeviceKeyID string `json:"device_key_id"`
|
||||
PoolID string `json:"pool_id"`
|
||||
IdempotencyKey string `json:"idempotency_key"`
|
||||
PolicySnapshot AllocationPolicy `json:"policy_snapshot"`
|
||||
ClientDeviceID string `json:"client_device_id"`
|
||||
DeviceKeyID string `json:"device_key_id"`
|
||||
PoolID string `json:"pool_id"`
|
||||
IdempotencyKey string `json:"idempotency_key"`
|
||||
PolicySnapshot AllocationPolicy `json:"policy_snapshot"`
|
||||
RequestedDisplayMode *DisplayMode `json:"requested_display_mode,omitempty"`
|
||||
}
|
||||
|
||||
type StableError struct {
|
||||
@@ -767,6 +777,16 @@ func (v BrokerSession) Validate() error {
|
||||
if v.Version != 0 && v.Version < 1 {
|
||||
violations = append(violations, FieldViolation{Field: "version", Code: "minimum"})
|
||||
}
|
||||
if v.RequestedDisplayMode != nil {
|
||||
if err := v.RequestedDisplayMode.Validate(); err != nil {
|
||||
violations = append(violations, FieldViolation{Field: "requested_display_mode", Code: "invalid_object"})
|
||||
}
|
||||
}
|
||||
if v.EffectiveDisplayMode != nil {
|
||||
if err := v.EffectiveDisplayMode.Validate(); err != nil {
|
||||
violations = append(violations, FieldViolation{Field: "effective_display_mode", Code: "invalid_object"})
|
||||
}
|
||||
}
|
||||
if len(violations) > 0 {
|
||||
return ValidationError{Violations: violations}
|
||||
}
|
||||
@@ -812,6 +832,12 @@ func DecodeBrokerSession(data []byte) (BrokerSession, error) {
|
||||
if raw, ok := fields["version"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "version", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["requested_display_mode"]; ok && bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "requested_display_mode", Code: "invalid_object"}}}
|
||||
}
|
||||
if raw, ok := fields["effective_display_mode"]; ok && bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "effective_display_mode", Code: "invalid_object"}}}
|
||||
}
|
||||
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||
decoder.DisallowUnknownFields()
|
||||
if err := decoder.Decode(&value); err != nil {
|
||||
@@ -1625,6 +1651,84 @@ func EncodeDeviceRegistrationRequest(value DeviceRegistrationRequest) ([]byte, e
|
||||
return json.Marshal(value)
|
||||
}
|
||||
|
||||
func (v DisplayMode) Validate() error {
|
||||
var violations []FieldViolation
|
||||
if v.ResolutionWidth == 0 {
|
||||
violations = append(violations, FieldViolation{Field: "resolution_width", Code: "required"})
|
||||
}
|
||||
if v.ResolutionWidth != 0 && v.ResolutionWidth < 320 {
|
||||
violations = append(violations, FieldViolation{Field: "resolution_width", Code: "minimum"})
|
||||
}
|
||||
if v.ResolutionWidth > 16384 {
|
||||
violations = append(violations, FieldViolation{Field: "resolution_width", Code: "maximum"})
|
||||
}
|
||||
if v.ResolutionHeight == 0 {
|
||||
violations = append(violations, FieldViolation{Field: "resolution_height", Code: "required"})
|
||||
}
|
||||
if v.ResolutionHeight != 0 && v.ResolutionHeight < 200 {
|
||||
violations = append(violations, FieldViolation{Field: "resolution_height", Code: "minimum"})
|
||||
}
|
||||
if v.ResolutionHeight > 8640 {
|
||||
violations = append(violations, FieldViolation{Field: "resolution_height", Code: "maximum"})
|
||||
}
|
||||
if v.Fps == 0 {
|
||||
violations = append(violations, FieldViolation{Field: "fps", Code: "required"})
|
||||
}
|
||||
if v.Fps != 0 && v.Fps < 1 {
|
||||
violations = append(violations, FieldViolation{Field: "fps", Code: "minimum"})
|
||||
}
|
||||
if v.Fps > 240 {
|
||||
violations = append(violations, FieldViolation{Field: "fps", Code: "maximum"})
|
||||
}
|
||||
if len(violations) > 0 {
|
||||
return ValidationError{Violations: violations}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DecodeDisplayMode(data []byte) (DisplayMode, error) {
|
||||
var value DisplayMode
|
||||
if len(data) > 1024*1024 {
|
||||
return value, errors.New("protocol payload exceeds limit")
|
||||
}
|
||||
var fields map[string]json.RawMessage
|
||||
if err := json.Unmarshal(data, &fields); err != nil {
|
||||
return value, err
|
||||
}
|
||||
if raw, ok := fields["fps"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "fps", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["resolution_height"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "resolution_height", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["resolution_width"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "resolution_width", Code: "required"}}}
|
||||
}
|
||||
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||
decoder.DisallowUnknownFields()
|
||||
if err := decoder.Decode(&value); err != nil {
|
||||
return value, err
|
||||
}
|
||||
var trailing any
|
||||
if err := decoder.Decode(&trailing); err != io.EOF {
|
||||
if err == nil {
|
||||
return value, errors.New("trailing JSON value")
|
||||
}
|
||||
return value, err
|
||||
}
|
||||
if err := value.Validate(); err != nil {
|
||||
return value, err
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func EncodeDisplayMode(value DisplayMode) ([]byte, error) {
|
||||
if err := value.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(value)
|
||||
}
|
||||
|
||||
func (v EntitledPool) Validate() error {
|
||||
var violations []FieldViolation
|
||||
if v.PoolID == "" {
|
||||
@@ -3202,6 +3306,11 @@ func (v ManifestProfile) Validate() error {
|
||||
if err := v.Bounds.Validate(); err != nil {
|
||||
violations = append(violations, FieldViolation{Field: "bounds", Code: "invalid_object"})
|
||||
}
|
||||
if v.DisplayMode != nil {
|
||||
if err := v.DisplayMode.Validate(); err != nil {
|
||||
violations = append(violations, FieldViolation{Field: "display_mode", Code: "invalid_object"})
|
||||
}
|
||||
}
|
||||
if len(violations) > 0 {
|
||||
return ValidationError{Violations: violations}
|
||||
}
|
||||
@@ -3223,6 +3332,9 @@ func DecodeManifestProfile(data []byte) (ManifestProfile, error) {
|
||||
if raw, ok := fields["id"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "id", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["display_mode"]; ok && bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "display_mode", Code: "invalid_object"}}}
|
||||
}
|
||||
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||
decoder.DisallowUnknownFields()
|
||||
if err := decoder.Decode(&value); err != nil {
|
||||
@@ -4655,6 +4767,11 @@ func (v SessionRequest) Validate() error {
|
||||
if err := v.PolicySnapshot.Validate(); err != nil {
|
||||
violations = append(violations, FieldViolation{Field: "policy_snapshot", Code: "invalid_object"})
|
||||
}
|
||||
if v.RequestedDisplayMode != nil {
|
||||
if err := v.RequestedDisplayMode.Validate(); err != nil {
|
||||
violations = append(violations, FieldViolation{Field: "requested_display_mode", Code: "invalid_object"})
|
||||
}
|
||||
}
|
||||
if len(violations) > 0 {
|
||||
return ValidationError{Violations: violations}
|
||||
}
|
||||
@@ -4685,6 +4802,9 @@ func DecodeSessionRequest(data []byte) (SessionRequest, error) {
|
||||
if raw, ok := fields["pool_id"]; !ok || bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "pool_id", Code: "required"}}}
|
||||
}
|
||||
if raw, ok := fields["requested_display_mode"]; ok && bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
|
||||
return value, ValidationError{Violations: []FieldViolation{{Field: "requested_display_mode", Code: "invalid_object"}}}
|
||||
}
|
||||
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||
decoder.DisallowUnknownFields()
|
||||
if err := decoder.Decode(&value); err != nil {
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@
|
||||
"2"
|
||||
]
|
||||
},
|
||||
"generator_sha256": "00fdba050eb924a54dd3d63aac0a38560341b675f0de4e3e9631ee895057a9b6",
|
||||
"generator_sha256": "992235a56d3467313148f86e47931f247591e4c8de737b55ac9c9eee35725fc5",
|
||||
"protocol_version": "1.0.0",
|
||||
"schema_sha256": "a86cbdaf2cfb884e3d98467968007e731ca55c6f6eb6dbd5cd6b95e062a9b058"
|
||||
"schema_sha256": "b2bb0a8ac8ef56dbc0e1443eeb5b3028be9e71ec2f5fd8e73928d71b7cd9340c"
|
||||
}
|
||||
|
||||
+54
-7
@@ -1,6 +1,6 @@
|
||||
// Code generated by tools/generate.py; DO NOT EDIT.
|
||||
#![allow(non_snake_case)]
|
||||
pub const SCHEMA_SHA256: &str = "a86cbdaf2cfb884e3d98467968007e731ca55c6f6eb6dbd5cd6b95e062a9b058";
|
||||
pub const SCHEMA_SHA256: &str = "b2bb0a8ac8ef56dbc0e1443eeb5b3028be9e71ec2f5fd8e73928d71b7cd9340c";
|
||||
pub const CURRENT_WIRE_VERSION: &str = "1";
|
||||
pub const N_MINUS_1_WIRE_VERSION: &str = "0";
|
||||
pub const N_MINUS_2_WIRE_VERSION: &str = "-1";
|
||||
@@ -136,11 +136,13 @@ pub struct BrokerSession {
|
||||
requestedAt: String,
|
||||
endedAt: Option<String>,
|
||||
version: i64,
|
||||
requestedDisplayMode: Option<DisplayMode>,
|
||||
effectiveDisplayMode: Option<DisplayMode>,
|
||||
}
|
||||
|
||||
impl BrokerSession {
|
||||
pub fn new(id: String, principalId: String, poolId: String, assignmentId: Option<String>, state: String, policySnapshot: AllocationPolicy, reconnectDeadline: Option<String>, outcome: Option<String>, failureCode: Option<String>, cleanupState: String, idempotencyKey: String, correlationId: String, requestedAt: String, endedAt: Option<String>, version: i64) -> Result<Self, ValidationError> {
|
||||
let value = Self { id, principalId, poolId, assignmentId, state, policySnapshot, reconnectDeadline, outcome, failureCode, cleanupState, idempotencyKey, correlationId, requestedAt, endedAt, version };
|
||||
pub fn new(id: String, principalId: String, poolId: String, assignmentId: Option<String>, state: String, policySnapshot: AllocationPolicy, reconnectDeadline: Option<String>, outcome: Option<String>, failureCode: Option<String>, cleanupState: String, idempotencyKey: String, correlationId: String, requestedAt: String, endedAt: Option<String>, version: i64, requestedDisplayMode: Option<DisplayMode>, effectiveDisplayMode: Option<DisplayMode>) -> Result<Self, ValidationError> {
|
||||
let value = Self { id, principalId, poolId, assignmentId, state, policySnapshot, reconnectDeadline, outcome, failureCode, cleanupState, idempotencyKey, correlationId, requestedAt, endedAt, version, requestedDisplayMode, effectiveDisplayMode };
|
||||
value.validate()?;
|
||||
Ok(value)
|
||||
}
|
||||
@@ -184,6 +186,12 @@ impl BrokerSession {
|
||||
if value.len() > 64 { return Err(ValidationError::new("ended_at", "max_length")); }
|
||||
}
|
||||
if self.version < 1 { return Err(ValidationError::new("version", "minimum")); }
|
||||
if let Some(value) = &self.requestedDisplayMode {
|
||||
value.validate().map_err(|_| ValidationError::new("requested_display_mode", "invalid_object"))?;
|
||||
}
|
||||
if let Some(value) = &self.effectiveDisplayMode {
|
||||
value.validate().map_err(|_| ValidationError::new("effective_display_mode", "invalid_object"))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn id(&self) -> &String { &self.id }
|
||||
@@ -201,6 +209,8 @@ impl BrokerSession {
|
||||
pub fn requestedAt(&self) -> &String { &self.requestedAt }
|
||||
pub fn endedAt(&self) -> &Option<String> { &self.endedAt }
|
||||
pub fn version(&self) -> &i64 { &self.version }
|
||||
pub fn requestedDisplayMode(&self) -> &Option<DisplayMode> { &self.requestedDisplayMode }
|
||||
pub fn effectiveDisplayMode(&self) -> &Option<DisplayMode> { &self.effectiveDisplayMode }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@@ -494,6 +504,33 @@ impl DeviceRegistrationRequest {
|
||||
pub fn publicKey(&self) -> &String { &self.publicKey }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct DisplayMode {
|
||||
resolutionWidth: i64,
|
||||
resolutionHeight: i64,
|
||||
fps: i64,
|
||||
}
|
||||
|
||||
impl DisplayMode {
|
||||
pub fn new(resolutionWidth: i64, resolutionHeight: i64, fps: i64) -> Result<Self, ValidationError> {
|
||||
let value = Self { resolutionWidth, resolutionHeight, fps };
|
||||
value.validate()?;
|
||||
Ok(value)
|
||||
}
|
||||
pub fn validate(&self) -> Result<(), ValidationError> {
|
||||
if self.resolutionWidth < 320 { return Err(ValidationError::new("resolution_width", "minimum")); }
|
||||
if self.resolutionWidth > 16384 { return Err(ValidationError::new("resolution_width", "maximum")); }
|
||||
if self.resolutionHeight < 200 { return Err(ValidationError::new("resolution_height", "minimum")); }
|
||||
if self.resolutionHeight > 8640 { return Err(ValidationError::new("resolution_height", "maximum")); }
|
||||
if self.fps < 1 { return Err(ValidationError::new("fps", "minimum")); }
|
||||
if self.fps > 240 { return Err(ValidationError::new("fps", "maximum")); }
|
||||
Ok(())
|
||||
}
|
||||
pub fn resolutionWidth(&self) -> &i64 { &self.resolutionWidth }
|
||||
pub fn resolutionHeight(&self) -> &i64 { &self.resolutionHeight }
|
||||
pub fn fps(&self) -> &i64 { &self.fps }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct EntitledPool {
|
||||
poolId: String,
|
||||
@@ -1080,11 +1117,12 @@ impl ManifestGateway {
|
||||
pub struct ManifestProfile {
|
||||
id: String,
|
||||
bounds: ManifestBounds,
|
||||
displayMode: Option<DisplayMode>,
|
||||
}
|
||||
|
||||
impl ManifestProfile {
|
||||
pub fn new(id: String, bounds: ManifestBounds) -> Result<Self, ValidationError> {
|
||||
let value = Self { id, bounds };
|
||||
pub fn new(id: String, bounds: ManifestBounds, displayMode: Option<DisplayMode>) -> Result<Self, ValidationError> {
|
||||
let value = Self { id, bounds, displayMode };
|
||||
value.validate()?;
|
||||
Ok(value)
|
||||
}
|
||||
@@ -1093,10 +1131,14 @@ impl ManifestProfile {
|
||||
if !self.id.is_empty() && self.id.len() < 1 { return Err(ValidationError::new("id", "min_length")); }
|
||||
if self.id.len() > 128 { return Err(ValidationError::new("id", "max_length")); }
|
||||
self.bounds.validate().map_err(|_| ValidationError::new("bounds", "invalid_object"))?;
|
||||
if let Some(value) = &self.displayMode {
|
||||
value.validate().map_err(|_| ValidationError::new("display_mode", "invalid_object"))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn id(&self) -> &String { &self.id }
|
||||
pub fn bounds(&self) -> &ManifestBounds { &self.bounds }
|
||||
pub fn displayMode(&self) -> &Option<DisplayMode> { &self.displayMode }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@@ -1613,11 +1655,12 @@ pub struct SessionRequest {
|
||||
poolId: String,
|
||||
idempotencyKey: String,
|
||||
policySnapshot: AllocationPolicy,
|
||||
requestedDisplayMode: Option<DisplayMode>,
|
||||
}
|
||||
|
||||
impl SessionRequest {
|
||||
pub fn new(clientDeviceId: String, deviceKeyId: String, poolId: String, idempotencyKey: String, policySnapshot: AllocationPolicy) -> Result<Self, ValidationError> {
|
||||
let value = Self { clientDeviceId, deviceKeyId, poolId, idempotencyKey, policySnapshot };
|
||||
pub fn new(clientDeviceId: String, deviceKeyId: String, poolId: String, idempotencyKey: String, policySnapshot: AllocationPolicy, requestedDisplayMode: Option<DisplayMode>) -> Result<Self, ValidationError> {
|
||||
let value = Self { clientDeviceId, deviceKeyId, poolId, idempotencyKey, policySnapshot, requestedDisplayMode };
|
||||
value.validate()?;
|
||||
Ok(value)
|
||||
}
|
||||
@@ -1635,6 +1678,9 @@ impl SessionRequest {
|
||||
if !self.idempotencyKey.is_empty() && self.idempotencyKey.len() < 1 { return Err(ValidationError::new("idempotency_key", "min_length")); }
|
||||
if self.idempotencyKey.len() > 256 { return Err(ValidationError::new("idempotency_key", "max_length")); }
|
||||
self.policySnapshot.validate().map_err(|_| ValidationError::new("policy_snapshot", "invalid_object"))?;
|
||||
if let Some(value) = &self.requestedDisplayMode {
|
||||
value.validate().map_err(|_| ValidationError::new("requested_display_mode", "invalid_object"))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn clientDeviceId(&self) -> &String { &self.clientDeviceId }
|
||||
@@ -1642,6 +1688,7 @@ impl SessionRequest {
|
||||
pub fn poolId(&self) -> &String { &self.poolId }
|
||||
pub fn idempotencyKey(&self) -> &String { &self.idempotencyKey }
|
||||
pub fn policySnapshot(&self) -> &AllocationPolicy { &self.policySnapshot }
|
||||
pub fn requestedDisplayMode(&self) -> &Option<DisplayMode> { &self.requestedDisplayMode }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by tools/generate.py; DO NOT EDIT.
|
||||
import Foundation
|
||||
public typealias JSONObject = [String: String]
|
||||
public let schemaSHA256 = "a86cbdaf2cfb884e3d98467968007e731ca55c6f6eb6dbd5cd6b95e062a9b058"
|
||||
public let schemaSHA256 = "b2bb0a8ac8ef56dbc0e1443eeb5b3028be9e71ec2f5fd8e73928d71b7cd9340c"
|
||||
public let currentWireVersion = "1"
|
||||
public let nMinus1WireVersion = "0"
|
||||
public let nMinus2WireVersion = "-1"
|
||||
@@ -148,6 +148,8 @@ public struct BrokerSession: Codable, Equatable {
|
||||
public let requestedAt: String
|
||||
public let endedAt: String?
|
||||
public let version: Int64
|
||||
public let requestedDisplayMode: DisplayMode?
|
||||
public let effectiveDisplayMode: DisplayMode?
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id = "id"
|
||||
case principalId = "principal_id"
|
||||
@@ -164,9 +166,11 @@ public struct BrokerSession: Codable, Equatable {
|
||||
case requestedAt = "requested_at"
|
||||
case endedAt = "ended_at"
|
||||
case version = "version"
|
||||
case requestedDisplayMode = "requested_display_mode"
|
||||
case effectiveDisplayMode = "effective_display_mode"
|
||||
}
|
||||
|
||||
public init(id: String, principalId: String, poolId: String, assignmentId: String?, state: String, policySnapshot: AllocationPolicy, reconnectDeadline: String?, outcome: String?, failureCode: String?, cleanupState: String, idempotencyKey: String, correlationId: String, requestedAt: String, endedAt: String?, version: Int64) throws {
|
||||
public init(id: String, principalId: String, poolId: String, assignmentId: String?, state: String, policySnapshot: AllocationPolicy, reconnectDeadline: String?, outcome: String?, failureCode: String?, cleanupState: String, idempotencyKey: String, correlationId: String, requestedAt: String, endedAt: String?, version: Int64, requestedDisplayMode: DisplayMode?, effectiveDisplayMode: DisplayMode?) throws {
|
||||
self.id = id
|
||||
self.principalId = principalId
|
||||
self.poolId = poolId
|
||||
@@ -182,6 +186,8 @@ public struct BrokerSession: Codable, Equatable {
|
||||
self.requestedAt = requestedAt
|
||||
self.endedAt = endedAt
|
||||
self.version = version
|
||||
self.requestedDisplayMode = requestedDisplayMode
|
||||
self.effectiveDisplayMode = effectiveDisplayMode
|
||||
try validate()
|
||||
}
|
||||
|
||||
@@ -189,7 +195,7 @@ public struct BrokerSession: Codable, Equatable {
|
||||
let all = try decoder.container(keyedBy: AnyCodingKey.self)
|
||||
for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") }
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
try self.init(id: try c.decode(String.self, forKey: .id), principalId: try c.decode(String.self, forKey: .principalId), poolId: try c.decode(String.self, forKey: .poolId), assignmentId: try c.decodeIfPresent(String.self, forKey: .assignmentId), state: try c.decode(String.self, forKey: .state), policySnapshot: try c.decode(AllocationPolicy.self, forKey: .policySnapshot), reconnectDeadline: try c.decodeIfPresent(String.self, forKey: .reconnectDeadline), outcome: try c.decodeIfPresent(String.self, forKey: .outcome), failureCode: try c.decodeIfPresent(String.self, forKey: .failureCode), cleanupState: try c.decode(String.self, forKey: .cleanupState), idempotencyKey: try c.decode(String.self, forKey: .idempotencyKey), correlationId: try c.decode(String.self, forKey: .correlationId), requestedAt: try c.decode(String.self, forKey: .requestedAt), endedAt: try c.decodeIfPresent(String.self, forKey: .endedAt), version: try c.decode(Int64.self, forKey: .version))
|
||||
try self.init(id: try c.decode(String.self, forKey: .id), principalId: try c.decode(String.self, forKey: .principalId), poolId: try c.decode(String.self, forKey: .poolId), assignmentId: try c.decodeIfPresent(String.self, forKey: .assignmentId), state: try c.decode(String.self, forKey: .state), policySnapshot: try c.decode(AllocationPolicy.self, forKey: .policySnapshot), reconnectDeadline: try c.decodeIfPresent(String.self, forKey: .reconnectDeadline), outcome: try c.decodeIfPresent(String.self, forKey: .outcome), failureCode: try c.decodeIfPresent(String.self, forKey: .failureCode), cleanupState: try c.decode(String.self, forKey: .cleanupState), idempotencyKey: try c.decode(String.self, forKey: .idempotencyKey), correlationId: try c.decode(String.self, forKey: .correlationId), requestedAt: try c.decode(String.self, forKey: .requestedAt), endedAt: try c.decodeIfPresent(String.self, forKey: .endedAt), version: try c.decode(Int64.self, forKey: .version), requestedDisplayMode: try c.contains(.requestedDisplayMode) ? c.decode(DisplayMode.self, forKey: .requestedDisplayMode) : nil, effectiveDisplayMode: try c.contains(.effectiveDisplayMode) ? c.decode(DisplayMode.self, forKey: .effectiveDisplayMode) : nil)
|
||||
}
|
||||
|
||||
public func validate() throws {
|
||||
@@ -235,6 +241,12 @@ public struct BrokerSession: Codable, Equatable {
|
||||
if ISO8601DateFormatter().date(from: value) == nil { throw ContractValidationError(field: "ended_at", code: "invalid_time") }
|
||||
}
|
||||
if self.version < 1 { throw ContractValidationError(field: "version", code: "minimum") }
|
||||
if let value = self.requestedDisplayMode {
|
||||
try value.validate()
|
||||
}
|
||||
if let value = self.effectiveDisplayMode {
|
||||
try value.validate()
|
||||
}
|
||||
}
|
||||
|
||||
public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) }
|
||||
@@ -632,6 +644,43 @@ public struct DeviceRegistrationRequest: Codable, Equatable {
|
||||
public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) }
|
||||
}
|
||||
|
||||
public struct DisplayMode: Codable, Equatable {
|
||||
public let resolutionWidth: Int64
|
||||
public let resolutionHeight: Int64
|
||||
public let fps: Int64
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case resolutionWidth = "resolution_width"
|
||||
case resolutionHeight = "resolution_height"
|
||||
case fps = "fps"
|
||||
}
|
||||
|
||||
public init(resolutionWidth: Int64, resolutionHeight: Int64, fps: Int64) throws {
|
||||
self.resolutionWidth = resolutionWidth
|
||||
self.resolutionHeight = resolutionHeight
|
||||
self.fps = fps
|
||||
try validate()
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let all = try decoder.container(keyedBy: AnyCodingKey.self)
|
||||
for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") }
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
try self.init(resolutionWidth: try c.decode(Int64.self, forKey: .resolutionWidth), resolutionHeight: try c.decode(Int64.self, forKey: .resolutionHeight), fps: try c.decode(Int64.self, forKey: .fps))
|
||||
}
|
||||
|
||||
public func validate() throws {
|
||||
if self.resolutionWidth < 320 { throw ContractValidationError(field: "resolution_width", code: "minimum") }
|
||||
if self.resolutionWidth > 16384 { throw ContractValidationError(field: "resolution_width", code: "maximum") }
|
||||
if self.resolutionHeight < 200 { throw ContractValidationError(field: "resolution_height", code: "minimum") }
|
||||
if self.resolutionHeight > 8640 { throw ContractValidationError(field: "resolution_height", code: "maximum") }
|
||||
if self.fps < 1 { throw ContractValidationError(field: "fps", code: "minimum") }
|
||||
if self.fps > 240 { throw ContractValidationError(field: "fps", code: "maximum") }
|
||||
}
|
||||
|
||||
public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) }
|
||||
public func encodeJSON() throws -> Data { try validate(); return try JSONEncoder().encode(self) }
|
||||
}
|
||||
|
||||
public struct EntitledPool: Codable, Equatable {
|
||||
public let poolId: String
|
||||
public let name: String
|
||||
@@ -1414,14 +1463,17 @@ public struct ManifestGateway: Codable, Equatable {
|
||||
public struct ManifestProfile: Codable, Equatable {
|
||||
public let id: String
|
||||
public let bounds: ManifestBounds
|
||||
public let displayMode: DisplayMode?
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id = "id"
|
||||
case bounds = "bounds"
|
||||
case displayMode = "display_mode"
|
||||
}
|
||||
|
||||
public init(id: String, bounds: ManifestBounds) throws {
|
||||
public init(id: String, bounds: ManifestBounds, displayMode: DisplayMode?) throws {
|
||||
self.id = id
|
||||
self.bounds = bounds
|
||||
self.displayMode = displayMode
|
||||
try validate()
|
||||
}
|
||||
|
||||
@@ -1429,7 +1481,7 @@ public struct ManifestProfile: Codable, Equatable {
|
||||
let all = try decoder.container(keyedBy: AnyCodingKey.self)
|
||||
for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") }
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
try self.init(id: try c.decode(String.self, forKey: .id), bounds: try c.decode(ManifestBounds.self, forKey: .bounds))
|
||||
try self.init(id: try c.decode(String.self, forKey: .id), bounds: try c.decode(ManifestBounds.self, forKey: .bounds), displayMode: try c.contains(.displayMode) ? c.decode(DisplayMode.self, forKey: .displayMode) : nil)
|
||||
}
|
||||
|
||||
public func validate() throws {
|
||||
@@ -1437,6 +1489,9 @@ public struct ManifestProfile: Codable, Equatable {
|
||||
if !self.id.isEmpty && self.id.utf8.count < 1 { throw ContractValidationError(field: "id", code: "min_length") }
|
||||
if self.id.utf8.count > 128 { throw ContractValidationError(field: "id", code: "max_length") }
|
||||
try self.bounds.validate()
|
||||
if let value = self.displayMode {
|
||||
try value.validate()
|
||||
}
|
||||
}
|
||||
|
||||
public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) }
|
||||
@@ -2132,20 +2187,23 @@ public struct SessionRequest: Codable, Equatable {
|
||||
public let poolId: String
|
||||
public let idempotencyKey: String
|
||||
public let policySnapshot: AllocationPolicy
|
||||
public let requestedDisplayMode: DisplayMode?
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case clientDeviceId = "client_device_id"
|
||||
case deviceKeyId = "device_key_id"
|
||||
case poolId = "pool_id"
|
||||
case idempotencyKey = "idempotency_key"
|
||||
case policySnapshot = "policy_snapshot"
|
||||
case requestedDisplayMode = "requested_display_mode"
|
||||
}
|
||||
|
||||
public init(clientDeviceId: String, deviceKeyId: String, poolId: String, idempotencyKey: String, policySnapshot: AllocationPolicy) throws {
|
||||
public init(clientDeviceId: String, deviceKeyId: String, poolId: String, idempotencyKey: String, policySnapshot: AllocationPolicy, requestedDisplayMode: DisplayMode?) throws {
|
||||
self.clientDeviceId = clientDeviceId
|
||||
self.deviceKeyId = deviceKeyId
|
||||
self.poolId = poolId
|
||||
self.idempotencyKey = idempotencyKey
|
||||
self.policySnapshot = policySnapshot
|
||||
self.requestedDisplayMode = requestedDisplayMode
|
||||
try validate()
|
||||
}
|
||||
|
||||
@@ -2153,7 +2211,7 @@ public struct SessionRequest: Codable, Equatable {
|
||||
let all = try decoder.container(keyedBy: AnyCodingKey.self)
|
||||
for key in all.allKeys where CodingKeys(stringValue: key.stringValue) == nil { throw ContractValidationError(field: key.stringValue, code: "unknown_field") }
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
try self.init(clientDeviceId: try c.decode(String.self, forKey: .clientDeviceId), deviceKeyId: try c.decode(String.self, forKey: .deviceKeyId), poolId: try c.decode(String.self, forKey: .poolId), idempotencyKey: try c.decode(String.self, forKey: .idempotencyKey), policySnapshot: try c.decode(AllocationPolicy.self, forKey: .policySnapshot))
|
||||
try self.init(clientDeviceId: try c.decode(String.self, forKey: .clientDeviceId), deviceKeyId: try c.decode(String.self, forKey: .deviceKeyId), poolId: try c.decode(String.self, forKey: .poolId), idempotencyKey: try c.decode(String.self, forKey: .idempotencyKey), policySnapshot: try c.decode(AllocationPolicy.self, forKey: .policySnapshot), requestedDisplayMode: try c.contains(.requestedDisplayMode) ? c.decode(DisplayMode.self, forKey: .requestedDisplayMode) : nil)
|
||||
}
|
||||
|
||||
public func validate() throws {
|
||||
@@ -2170,6 +2228,9 @@ public struct SessionRequest: Codable, Equatable {
|
||||
if !self.idempotencyKey.isEmpty && self.idempotencyKey.utf8.count < 1 { throw ContractValidationError(field: "idempotency_key", code: "min_length") }
|
||||
if self.idempotencyKey.utf8.count > 256 { throw ContractValidationError(field: "idempotency_key", code: "max_length") }
|
||||
try self.policySnapshot.validate()
|
||||
if let value = self.requestedDisplayMode {
|
||||
try value.validate()
|
||||
}
|
||||
}
|
||||
|
||||
public static func decodeJSON(_ data: Data) throws -> Self { try JSONDecoder().decode(Self.self, from: data) }
|
||||
|
||||
Reference in New Issue
Block a user