76 lines
1.8 KiB
Go
76 lines
1.8 KiB
Go
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
|
|
}
|