diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-10-26 01:49:14 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-10-26 01:49:14 +0900 |
| commit | 86f4219062ae4787ac9478b025abf8416e5593a2 (patch) | |
| tree | 6585322aa8f8234c42b355982c6dd66917220600 /internal/app/state/data.go | |
| parent | fe2929d5f7249f8593923446e1c327bf503cc8a0 (diff) | |
internal/app/state/data: check full entry behaviour
This eventually gets relocated to internal/app.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/state/data.go')
| -rw-r--r-- | internal/app/state/data.go | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/internal/app/state/data.go b/internal/app/state/data.go new file mode 100644 index 00000000..3c289f94 --- /dev/null +++ b/internal/app/state/data.go @@ -0,0 +1,43 @@ +package state + +import ( + "encoding/gob" + "fmt" + "io" + "os" + + "hakurei.app/hst" +) + +// entryEncode encodes [hst.State] into [io.Writer] with the state entry header. +// entryEncode does not validate the embedded [hst.Config] value. +// +// A non-nil error returned by entryEncode is of type [hst.AppError]. +func entryEncode(w io.Writer, s *hst.State) error { + if err := entryWriteHeader(w, s.Enablements.Unwrap()); err != nil { + return &hst.AppError{Step: "encode state header", Err: err} + } else if err = gob.NewEncoder(w).Encode(s); err != nil { + return &hst.AppError{Step: "encode state body", Err: err} + } else { + return nil + } +} + +// entryDecode decodes [hst.State] from [io.Reader] and stores the result in the value pointed to by p. +// entryDecode validates the embedded [hst.Config] value. +// +// A non-nil error returned by entryDecode is of type [hst.AppError]. +func entryDecode(r io.Reader, p *hst.State) error { + if et, err := entryReadHeader(r); err != nil { + return &hst.AppError{Step: "decode state header", Err: err} + } else if err = gob.NewDecoder(r).Decode(&p); err != nil { + return &hst.AppError{Step: "decode state body", Err: err} + } else if err = p.Config.Validate(); err != nil { + return err + } else if p.Enablements.Unwrap() != et { + return &hst.AppError{Step: "validate state enablement", Err: os.ErrInvalid, + Msg: fmt.Sprintf("state entry %s has unexpected enablement byte %#x, %#x", p.ID.String(), byte(p.Enablements.Unwrap()), byte(et))} + } else { + return nil + } +} |
