decodeEvent static method

JackfieldEvent decodeEvent(
  1. Object? payload
)

Decodes one event, rejecting unknown or malformed payloads safely.

Implementation

static JackfieldEvent decodeEvent(Object? payload) {
  if (payload is! Map) {
    throw const JackfieldProtocolException('Expected an event object');
  }
  final data = <String, Object?>{};
  for (final entry in payload.entries) {
    if (entry.key is! String) {
      throw const JackfieldProtocolException('Expected string field names');
    }
    data[entry.key as String] = entry.value;
  }
  if (data['version'] is! int || data['version'] != version) {
    throw const JackfieldProtocolException('Unsupported event version');
  }
  final type = data['type'];
  final requiredKeys = switch (type) {
    'answer_requested' => const {
      'version',
      'type',
      'callId',
      'actionId',
      'eventId',
      'sequence',
      'occurredAt',
      'deadline',
    },
    'ended' => const {
      'version',
      'type',
      'callId',
      'eventId',
      'sequence',
      'occurredAt',
      'reason',
    },
    _ => throw const JackfieldProtocolException('Unknown event type'),
  };
  if (data.keys.toSet().difference(requiredKeys).isNotEmpty ||
      requiredKeys.difference(data.keys.toSet()).isNotEmpty) {
    throw const JackfieldProtocolException('Invalid event fields');
  }
  final callId = CallId(_nonemptyString(data, 'callId'));
  final eventId = EventId(_nonemptyString(data, 'eventId'));
  final sequence = data['sequence'];
  if (sequence is! int || sequence < 0) {
    throw const JackfieldProtocolException('Invalid event sequence');
  }
  final occurredAt = _timestamp(data, 'occurredAt');
  return switch (type) {
    'answer_requested' => AnswerRequested(
      callId: callId,
      eventId: eventId,
      sequence: sequence,
      occurredAt: occurredAt,
      actionId: ActionId(_nonemptyString(data, 'actionId')),
      deadline: _timestamp(data, 'deadline'),
    ),
    'ended' => CallEnded(
      callId: callId,
      eventId: eventId,
      sequence: sequence,
      occurredAt: occurredAt,
      reason: _endReason(data),
    ),
    _ => throw const JackfieldProtocolException('Unknown event type'),
  };
}