package seriatim import ( "bytes" "encoding/json" "fmt" "io" ) type transcript struct { Metadata map[string]any `json:"metadata"` Segments []segment `json:"segments"` } type segment struct { ID string `json:"id"` Start json.Number `json:"start"` End json.Number `json:"end"` Speaker string `json:"speaker"` Text string `json:"text"` } func decodeTranscript(raw []byte) (transcript, error) { var fields map[string]json.RawMessage if err := decodeJSON(raw, &fields); err != nil { return transcript{}, err } if fields == nil { return transcript{}, fmt.Errorf("top-level value must be an object") } metadataRaw, ok := fields["metadata"] if !ok { return transcript{}, fmt.Errorf("metadata is required") } var metadata map[string]any if err := decodeJSON(metadataRaw, &metadata); err != nil { return transcript{}, fmt.Errorf("metadata must be an object: %w", err) } if metadata == nil { return transcript{}, fmt.Errorf("metadata must be an object") } segmentsRaw, ok := fields["segments"] if !ok { return transcript{}, fmt.Errorf("segments are required") } var segments []segment if err := decodeJSON(segmentsRaw, &segments); err != nil { return transcript{}, fmt.Errorf("segments must be an array: %w", err) } if segments == nil { return transcript{}, fmt.Errorf("segments must be an array") } return transcript{ Metadata: metadata, Segments: segments, }, nil } func decodeJSON(raw []byte, out any) error { decoder := json.NewDecoder(bytes.NewReader(raw)) decoder.UseNumber() if err := decoder.Decode(out); err != nil { return err } if err := decoder.Decode(&struct{}{}); err != io.EOF { if err == nil { return fmt.Errorf("unexpected trailing JSON value") } return err } return nil }