soup-sdk 0.3.5

채팅 이벤트 수신 SDK
Documentation
# SOOP SDK Architecture

This document describes the current architecture and the intended direction for future refactors.

## Current Shape

The SDK currently exposes three main capabilities:

- HTTP API access through `SoopHttpClient` backed by shared `api` helpers.
- Live chat streaming through `SoopChatConnection`.
- VOD chat XML parsing through `parse_vod_chat_xml_with_start_time` and helper methods on `SoopHttpClient`.

Public re-exports are centered in `src/lib.rs`:

- `SoopHttpClient`
- `Error` and `Result`
- `Event`
- VOD models
- VOD chat XML parser

## HTTP Flow

Current flow:

```text
SoopHttpClient method
  -> reqwest request
  -> status check
  -> raw response DTO
  -> public model conversion
```

Important files:

- `src/api.rs`: shared request helpers, common headers, status validation, and decode helpers.
- `src/client.rs`: public HTTP methods and DTO conversion orchestration.
- `src/models.rs`: raw response models, public models, and conversion helpers.
- `src/constants.rs`: shared endpoint constants.
- `src/error.rs`: SDK error type.

Current HTTP methods:

- `get_live_status(streamer_id) -> Result<LiveStatus>`
- `get_station(streamer_id) -> Result<Station>`
- `get_signature_emoticon(streamer_id) -> Result<SignatureEmoticonData>`
- `get_vod_list(streamer_id, page) -> Result<Vec<VOD>>`
- `get_vod_detail(vod_id) -> Result<VODDetail>`
- `get_vod_chat(chat_url, start_time) -> Result<String>`
- `get_full_vod_chat(vod_id) -> Result<VodChatCollection>`

## Live Chat Flow

Current flow:

```text
SoopChatConnection::new
  -> create command channel
  -> create broadcast event channel

SoopChatConnection::start
  -> fetch live detail with SoopHttpClient
  -> build WebSocket URL
  -> spawn background connection task

connection task
  -> open WebSocket
  -> emit Event::Connected
  -> send Connect packet
  -> receive server packets
  -> MessageHandler::handle
  -> parser dispatch
  -> emit Event
```

Important files:

- `src/chat/connection.rs`: connection lifecycle, command receiver, ping loop.
- `src/chat/formatter.rs`: outgoing protocol packet formatting.
- `src/chat/commands.rs`: outgoing command and message type definitions.
- `src/chat/message.rs`: incoming message dispatch and event broadcasting.
- `src/chat/events.rs`: public event enum and payload structs.

Current lifecycle notes:

- A `SoopChatConnection` can be started only once.
- Subscribers may call `subscribe()` before or after `start()`.
- `Command::Shutdown` stops the active communication loop.
- Chat sending is not exposed in v0.3.
- The connection loop does not automatically reconnect. Terminal sessions emit `Disconnected` with a reason.
- WebSocket connection attempts use a 15-second timeout.
- TLS certificate verification is currently disabled for the live chat WebSocket connection.

## Parser Flow

Current flow:

```text
WebSocket binary frame
  -> Diagnostic(RawFrame) broadcast when diagnostics is enabled
  -> parse_message
  -> RawMessage { code, ret_code, body, received_time, raw }
  -> Diagnostic(DecodedFrame) broadcast when diagnostics is enabled
  -> MessageHandler code match
  -> parse_*_event
  -> typed Event or Diagnostic(ParseFailed) broadcast when diagnostics is enabled
```

Raw chat packets use:

- 14-byte header.
- message code at header bytes `2..6`.
- return code at header bytes `12..14`.
- body after byte `14`.
- form-feed separator `0x0c` for body fields.

Important files:

- `src/chat/parser/raw.rs`: raw frame parsing.
- `src/chat/constants.rs`: protocol separators, message codes, common body indexes.
- `src/chat/parser/*.rs`: event-specific body parsers.

Current parser risk:

- Parsers use shared safe field accessors on `RawMessage`.
- Malformed packets become `Diagnostic(ParseFailed)` when diagnostics is enabled instead of panicking.

Current parser direction:

- Use shared safe field accessors on `RawMessage`.
- Return typed parse errors for missing fields, invalid numbers, and invalid JSON.
- Preserve raw packet context with diagnostic errors when diagnostics is enabled.
- Keep unknown message code reporting through `Event::Unknown`.
- Add replay tests for known raw frames.

## Event Model

`Event` is the public event enum. It is serialized with:

```rust
#[serde(tag = "type", content = "payload")]
```

This means JSON output uses a tagged form such as:

```json
{
  "type": "Chat",
  "payload": {
    "received_time": "2026-07-12T00:00:00Z",
    "comment": "hello"
  }
}
```

Every structured event payload includes `EventMeta`, currently `received_time`.

Diagnostic events:

- `Event::Unknown(code)` means the SDK decoded the frame but does not have a handler for the message code.
- `Event::Diagnostic(...)` carries raw frames, decoded fields, unknown codes, and parse failure context when `SoopChatOptions::diagnostics` is enabled.

Target event direction:

- Keep stable user-facing events separate from internal protocol diagnostics.
- Consider adding a structured debug/protocol event type for parse errors, unknown fields, and raw body inspection.
- Avoid removing `Raw` while protocol coverage is incomplete.

## VOD Chat Flow

Current VOD flow:

```text
get_vod_detail(vod_id)
  -> VODDetail files
  -> get_vod_chat(file.chat, start_time)
  -> XML string
  -> parse_vod_chat_xml_with_start_time
  -> Vec<Event>
```

Important files:

- `src/client.rs`: VOD list/detail/chat fetch helpers and `VodChatCollection` assembly.
- `src/vod_chat_parser.rs`: XML parser that maps VOD chat elements into `Event` values.

Current limitation:

- `get_full_vod_chat` records chunk-level successes and failures in `VodChatCollection`.

Target direction:

- Return structured collection results when partial VOD chat chunks fail.
- Add XML fixtures for each supported VOD chat element.
- Keep VOD events aligned with live `Event` payloads where possible.

## Target Refactor Map

Preferred future layers:

```text
api/
  request builders, endpoint constants, status handling

models/
  raw DTOs and public domain models

chat/session/
  connection lifecycle, reconnect policy, shutdown

chat/protocol/
  frame formatter, raw parser, message codes

chat/events/
  public events and diagnostics

fixtures/
  raw frames and VOD XML samples for parser tests
```

This layout is directional, not mandatory. Refactors should be incremental and keep public API compatibility where practical.