package storage import ( "context" "fmt" "io" "git.eeqj.de/sneak/vaultik/internal/s3" ) // S3Storer wraps the existing s3.Client to implement Storer. type S3Storer struct { client *s3.Client } // NewS3Storer creates a new S3 storage backend. func NewS3Storer(client *s3.Client) *S3Storer { return &S3Storer{client: client} } // Put stores data at the specified key. func (s *S3Storer) Put(ctx context.Context, key string, data io.Reader) error { return s.client.PutObject(ctx, key, data) } // PutWithProgress stores data with progress reporting. func (s *S3Storer) PutWithProgress(ctx context.Context, key string, data io.Reader, size int64, progress ProgressCallback) error { // Convert storage.ProgressCallback to s3.ProgressCallback var s3Progress s3.ProgressCallback if progress != nil { s3Progress = s3.ProgressCallback(progress) } return s.client.PutObjectWithProgress(ctx, key, data, size, s3Progress) } // Get retrieves data from the specified key. func (s *S3Storer) Get(ctx context.Context, key string) (io.ReadCloser, error) { return s.client.GetObject(ctx, key) } // Stat returns metadata about an object without retrieving its contents. func (s *S3Storer) Stat(ctx context.Context, key string) (*ObjectInfo, error) { info, err := s.client.StatObject(ctx, key) if err != nil { return nil, err } return &ObjectInfo{ Key: info.Key, Size: info.Size, }, nil } // Delete removes an object. func (s *S3Storer) Delete(ctx context.Context, key string) error { return s.client.DeleteObject(ctx, key) } // List returns all keys with the given prefix. func (s *S3Storer) List(ctx context.Context, prefix string) ([]string, error) { return s.client.ListObjects(ctx, prefix) } // ListStream returns a channel of ObjectInfo for large result sets. func (s *S3Storer) ListStream(ctx context.Context, prefix string) <-chan ObjectInfo { ch := make(chan ObjectInfo) go func() { defer close(ch) for info := range s.client.ListObjectsStream(ctx, prefix, false) { ch <- ObjectInfo{ Key: info.Key, Size: info.Size, Err: info.Err, } } }() return ch } // Info returns human-readable storage location information. func (s *S3Storer) Info() StorageInfo { return StorageInfo{ Type: "s3", Location: fmt.Sprintf("%s/%s", s.client.Endpoint(), s.client.BucketName()), } }