itd/api/fs.go

120 lines
2.8 KiB
Go
Raw Normal View History

2021-11-23 19:12:16 +00:00
package api
2023-01-03 06:30:17 +00:00
import (
"context"
"errors"
"io"
"go.arsenm.dev/itd/internal/rpc"
)
type FSClient struct {
client rpc.DRPCFSClient
}
func (c *FSClient) RemoveAll(ctx context.Context, paths ...string) error {
_, err := c.client.RemoveAll(ctx, &rpc.PathsRequest{Paths: paths})
return err
2022-09-03 23:28:25 +00:00
}
2023-01-03 06:30:17 +00:00
func (c *FSClient) Remove(ctx context.Context, paths ...string) error {
_, err := c.client.Remove(ctx, &rpc.PathsRequest{Paths: paths})
return err
2021-11-23 19:12:16 +00:00
}
2023-01-03 06:30:17 +00:00
func (c *FSClient) Rename(ctx context.Context, old, new string) error {
_, err := c.client.Rename(ctx, &rpc.RenameRequest{
From: old,
To: new,
})
return err
2021-11-23 19:12:16 +00:00
}
2023-01-03 06:30:17 +00:00
func (c *FSClient) MkdirAll(ctx context.Context, paths ...string) error {
_, err := c.client.MkdirAll(ctx, &rpc.PathsRequest{Paths: paths})
return err
2022-09-03 23:28:25 +00:00
}
2023-01-03 06:30:17 +00:00
func (c *FSClient) Mkdir(ctx context.Context, paths ...string) error {
_, err := c.client.Mkdir(ctx, &rpc.PathsRequest{Paths: paths})
return err
2021-11-23 19:12:16 +00:00
}
2023-01-03 06:30:17 +00:00
func (c *FSClient) ReadDir(ctx context.Context, dir string) ([]FileInfo, error) {
res, err := c.client.ReadDir(ctx, &rpc.PathRequest{Path: dir})
return convertEntries(res.Entries), err
}
func convertEntries(e []*rpc.FileInfo) []FileInfo {
out := make([]FileInfo, len(e))
for i, fi := range e {
out[i] = FileInfo{
Name: fi.Name,
Size: fi.Size,
IsDir: fi.IsDir,
}
}
return out
2021-11-23 19:12:16 +00:00
}
2023-01-03 06:30:17 +00:00
func (c *FSClient) Upload(ctx context.Context, dst, src string) (chan FSTransferProgress, error) {
progressCh := make(chan FSTransferProgress, 5)
2023-01-03 06:30:17 +00:00
tc, err := c.client.Upload(ctx, &rpc.TransferRequest{Source: src, Destination: dst})
2021-11-23 19:12:16 +00:00
if err != nil {
2021-12-13 01:08:48 +00:00
return nil, err
2021-11-23 19:12:16 +00:00
}
2021-12-13 01:08:48 +00:00
2023-01-03 06:30:17 +00:00
go fsRecvToChannel[rpc.TransferProgress](tc, progressCh, func(evt *rpc.TransferProgress, err error) FSTransferProgress {
return FSTransferProgress{
Sent: evt.Sent,
Total: evt.Total,
Err: err,
}
})
2022-04-23 00:12:30 +00:00
return progressCh, nil
}
2021-12-13 01:08:48 +00:00
2023-01-03 06:30:17 +00:00
func (c *FSClient) Download(ctx context.Context, dst, src string) (chan FSTransferProgress, error) {
progressCh := make(chan FSTransferProgress, 5)
2023-01-03 06:30:17 +00:00
tc, err := c.client.Download(ctx, &rpc.TransferRequest{Source: src, Destination: dst})
2021-11-23 19:12:16 +00:00
if err != nil {
2021-12-13 01:08:48 +00:00
return nil, err
2021-11-23 19:12:16 +00:00
}
2021-12-13 01:08:48 +00:00
2023-01-03 06:30:17 +00:00
go fsRecvToChannel[rpc.TransferProgress](tc, progressCh, func(evt *rpc.TransferProgress, err error) FSTransferProgress {
return FSTransferProgress{
Sent: evt.Sent,
Total: evt.Total,
Err: err,
}
})
2022-04-23 00:12:30 +00:00
return progressCh, nil
2021-11-23 19:12:16 +00:00
}
2023-01-03 06:30:17 +00:00
// fsRecvToChannel converts a DRPC stream client to a Go channel, using cf to convert
// RPC generated types to API response types.
func fsRecvToChannel[R any, A any](s StreamClient[R], ch chan<- A, cf func(evt *R, err error) A) {
defer close(ch)
var err error
var evt *R
for {
select {
case <-s.Context().Done():
return
default:
evt, err = s.Recv()
if errors.Is(err, io.EOF) {
return
} else if err != nil {
ch <- cf(new(R), err)
return
}
ch <- cf(evt, nil)
}
}
}