@@ -11,7 +11,9 @@ import (
1111 "crypto/rand"
1212 "fmt"
1313 "io"
14- "sync"
14+
15+ "github.com/siderolabs/gen/pair"
16+ "github.com/siderolabs/gen/xsync"
1517
1618 "github.com/cosi-project/runtime/pkg/resource"
1719 "github.com/cosi-project/runtime/pkg/state/impl/store"
@@ -56,48 +58,43 @@ func (m *Marshaler) UnmarshalResource(b []byte) (resource.Resource, error) { //n
5658// Cipher provides encryption and decryption.
5759type Cipher struct {
5860 keyProvider KeyProvider
59- once Once [cipherData ]
61+ once xsync. Once [pair. Pair [cipher. AEAD , error ] ]
6062}
6163
6264// NewCipher creates new Cipher.
6365func NewCipher (provider KeyProvider ) * Cipher {
6466 return & Cipher {keyProvider : provider }
6567}
6668
67- type cipherData struct {
68- aead cipher.AEAD
69- err error
70- }
71-
7269func (c * Cipher ) init () (cipher.AEAD , error ) {
73- res := c .once .Do (func () cipherData {
70+ res := c .once .Do (func () pair. Pair [cipher. AEAD , error ] {
7471 key , err := c .keyProvider .ProvideKey ()
7572 if err != nil {
76- return cipherData { err : fmt .Errorf ("failed to get key: %w" , err )}
73+ return pair . MakePair [cipher. AEAD , error ]( nil , fmt .Errorf ("failed to provide key: %w" , err ))
7774 }
7875
7976 if len (key ) != 32 {
80- return cipherData { err : fmt .Errorf ("key length is not 32 bytes" )}
77+ return pair . MakePair [cipher. AEAD , error ]( nil , fmt .Errorf ("key length is not 32 bytes" ))
8178 }
8279
8380 block , err := aes .NewCipher (key )
8481 if err != nil {
85- return cipherData { err : fmt .Errorf ("failed to create cipher: %w" , err )}
82+ return pair . MakePair [cipher. AEAD , error ]( nil , fmt .Errorf ("failed to create cipher: %w" , err ))
8683 }
8784
8885 aead , err := cipher .NewGCM (block )
8986 if err != nil {
90- return cipherData { err : fmt .Errorf ("failed to create GCM: %w" , err )}
87+ return pair . MakePair [cipher. AEAD , error ]( nil , fmt .Errorf ("failed to create GCM: %w" , err ))
9188 }
9289
93- return cipherData { aead : aead }
90+ return pair . MakePair [cipher. AEAD , error ]( aead , nil )
9491 })
95- if res .err != nil {
96- return nil , res .err
92+ if res .F2 != nil {
93+ return nil , res .F2
9794 }
9895
9996 // According to https://github.com/golang/go/issues/25882 cipher.AEAD is safe to share between goroutines.
100- return res .aead , nil
97+ return res .F1 , nil
10198}
10299
103100// Encrypt encrypts data.
@@ -159,18 +156,3 @@ type KeyProviderFunc func() ([]byte, error)
159156func (f KeyProviderFunc ) ProvideKey () ([]byte , error ) {
160157 return f ()
161158}
162-
163- // Once is small wrapper around [sync.Once]. It stores the result inside.
164- type Once [T any ] struct {
165- val T
166- once sync.Once
167- }
168-
169- // Do runs the function only once.
170- func (o * Once [T ]) Do (fn func () T ) T {
171- o .once .Do (func () {
172- o .val = fn ()
173- })
174-
175- return o .val
176- }
0 commit comments