Files
Bridge-and-Join-s/internal/nsdxml/README.md
T
fontvielle 1d6ab86a57 feat(m2m): доменная модель сообщений + парсер windows-1251 + round-trip тесты
- internal/m2m/types.go: enum'ы и simple-типы из XSD НРД (M2MSchemas_260408)
- internal/m2m/validators.go: pattern-валидаторы ReferenceID/ISIN/INN/UUID/SecurityCode/IdentityDocSerial/AccountID + перечисления
- internal/m2m/messages.go: структуры 6 типов сообщений M2M, choice-типы через указатели, IsM2M=true автоматически в MarshalXML
- internal/nsdxml/datetime.go: тип NSDDateTime (формат "YYYY-MM-DDThh:mm:ss(МСК+N)")
- internal/nsdxml/codec.go: Marshal/Unmarshal XML в windows-1251 (собственный кодек CP1251, без внешних зависимостей)
- internal/m2m/messages_test.go: round-trip тесты на 6 примерах + 2 эталонах из DOC/

Покрытие: m2m 73.9%, nsdxml 92.5%. make ci зелёный.

Отклонение от спеки: вместо golang.org/x/text/encoding/charmap собственная
таблица CP1251 на ~60 строк, потому что прокси zetit блокирует
proxy.golang.org, goproxy.cn и redirect-хосты Go-модулей.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 00:30:46 +03:00

2.4 KiB

internal/nsdxml — сериализация и парсинг XML по правилам НРД

Что реализовано

  • Marshal(v) ([]byte, error) / Unmarshal(data, v) error — сериализация и разбор XML с прологом <?xml version="1.0" encoding="windows-1251"?>. Unmarshal понимает как windows-1251, так и UTF-8 на входе через CharsetReader.
  • Кодек windows-1251 (собственный, без внешних зависимостей): EncodeWindows1251, DecodeWindows1251. Таблица соответствия CP1251 ↔ Unicode для байтов 0x80..0xFF. Руны, не выразимые в CP1251, приводят к ошибке ErrUnmappable.
  • CharsetReader(charset, input) — пригодно к использованию в xml.Decoder.CharsetReader. Поддерживает windows-1251, cp1251, utf-8, отсутствие charset; на другие — ошибка.
  • NSDDateTime — отметка времени НРД формата YYYY-MM-DDThh:mm:ss(МСК[+-N]), regex из XSD: [0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\(МСК([+-][0-9]{1,2})?\). Реализованы MarshalXML, UnmarshalXML, MarshalText, UnmarshalText, String, Now. Сохраняет различие между «(МСК)» без сдвига и «(МСК+0)» через OffsetSpecified.

Зачем свой кодек windows-1251

Сетевая политика dev-стенда блокирует proxy.golang.org, goproxy.cn и redirect-хосты Go-модулей (golang.org/x/*, google.golang.org/* и др.), поэтому штатный golang.org/x/text/encoding/charmap пакетным менеджером не устанавливается. Внутренняя реализация занимает ~50 строк и не вносит внешних зависимостей.

Тесты

  • Round-trip на ASCII и кириллице, включая cp1251-пунктуацию (, ©, «», „").
  • Негативный кейс — недостижимая руна (эмодзи) даёт ErrUnmappable.
  • NSDDateTime на всех вариантах смещения: (МСК), (МСК+2), (МСК-1), (МСК+12).
  • Покрытие — 92.5%.