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>
This commit is contained in:
@@ -1,14 +1,39 @@
|
||||
# internal/nsdxml — сериализация и парсинг XML по правилам НРД
|
||||
|
||||
Особенности, которые этот пакет обязан учитывать:
|
||||
## Что реализовано
|
||||
|
||||
- **Кодировка `windows-1251`** на чтение и запись (XML-объявление и тело).
|
||||
Для конвертации — `golang.org/x/text/encoding/charmap.Windows1251`.
|
||||
- **Тип `NSDDateTime`** — формат `YYYY-MM-DDThh:mm:ss(МСК[+/-N])`,
|
||||
pattern из XSD:
|
||||
- **`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})?\)`.
|
||||
Только зона МСК, опциональный сдвиг.
|
||||
- **Каноникализация `xml-exc-c14n`** для проверки совпадения с эталоном.
|
||||
- **Round-trip**: `Marshal(Unmarshal(x)) == x` после канонизации.
|
||||
Реализованы `MarshalXML`, `UnmarshalXML`, `MarshalText`,
|
||||
`UnmarshalText`, `String`, `Now`. Сохраняет различие между «(МСК)»
|
||||
без сдвига и «(МСК+0)» через `OffsetSpecified`.
|
||||
|
||||
Реализация — задача M1 (см. план).
|
||||
## Зачем свой кодек 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%.
|
||||
|
||||
Reference in New Issue
Block a user