master
go 135 lines 3.52 KB
Raw
1 package iface
2
3 import (
4 "context"
5 "iter"
6 "os"
7 "time"
8
9 "github.com/ipfs/boxo/files"
10 "github.com/ipfs/boxo/path"
11 "github.com/ipfs/go-cid"
12 "github.com/ipfs/kubo/core/coreiface/options"
13 )
14
15 type AddEvent struct {
16 Name string
17 Path path.ImmutablePath
18 Bytes int64 `json:",omitempty"`
19 Size string `json:",omitempty"`
20 Mode os.FileMode `json:",omitempty"`
21 Mtime int64 `json:",omitempty"`
22 MtimeNsecs int `json:",omitempty"`
23 }
24
25 // FileType is an enum of possible UnixFS file types.
26 type FileType int32
27
28 const (
29 // TUnknown means the file type isn't known (e.g., it hasn't been
30 // resolved).
31 TUnknown FileType = iota
32 // TFile is a regular file.
33 TFile
34 // TDirectory is a directory.
35 TDirectory
36 // TSymlink is a symlink.
37 TSymlink
38 )
39
40 func (t FileType) String() string {
41 switch t {
42 case TUnknown:
43 return "unknown"
44 case TFile:
45 return "file"
46 case TDirectory:
47 return "directory"
48 case TSymlink:
49 return "symlink"
50 default:
51 return "<unknown file type>"
52 }
53 }
54
55 // DirEntry is a directory entry returned by `Ls`.
56 type DirEntry struct {
57 Name string
58 Cid cid.Cid
59
60 // Only filled when asked to resolve the directory entry.
61 Size uint64 // The size of the file in bytes (or the size of the symlink).
62 Type FileType // The type of the file.
63 Target string // The symlink target (if a symlink).
64
65 Mode os.FileMode
66 ModTime time.Time
67 }
68
69 // UnixfsAPI is the basic interface to immutable files in IPFS
70 // NOTE: This API is heavily WIP, things are guaranteed to break frequently
71 type UnixfsAPI interface {
72 // Add imports the data from the reader into merkledag file
73 //
74 // TODO: a long useful comment on how to use this for many different scenarios
75 Add(context.Context, files.Node, ...options.UnixfsAddOption) (path.ImmutablePath, error)
76
77 // Get returns a read-only handle to a file tree referenced by a path
78 //
79 // Note that some implementations of this API may apply the specified context
80 // to operations performed on the returned file
81 Get(context.Context, path.Path) (files.Node, error)
82
83 // Ls writes the links in a directory to the DirEntry channel. Links aren't
84 // guaranteed to be returned in order. If an error occurs or the context is
85 // canceled, the DirEntry channel is closed and an error is returned.
86 //
87 // Example:
88 //
89 // dirs := make(chan DirEntry)
90 // lsErr := make(chan error, 1)
91 // go func() {
92 // lsErr <- Ls(ctx, p, dirs)
93 // }()
94 // for dirEnt := range dirs {
95 // fmt.Println("Dir name:", dirEnt.Name)
96 // }
97 // err := <-lsErr
98 // if err != nil {
99 // return fmt.Errorf("error listing directory: %w", err)
100 // }
101 Ls(context.Context, path.Path, chan<- DirEntry, ...options.UnixfsLsOption) error
102 }
103
104 // LsIter returns a go iterator that allows ranging over DirEntry results.
105 // Iteration stops if the context is canceled or if the iterator yields an
106 // error.
107 //
108 // Example:
109 //
110 // for dirEnt, err := LsIter(ctx, ufsAPI, p) {
111 // if err != nil {
112 // return fmt.Errorf("error listing directory: %w", err)
113 // }
114 // fmt.Println("Dir name:", dirEnt.Name)
115 // }
116 func LsIter(ctx context.Context, api UnixfsAPI, p path.Path, opts ...options.UnixfsLsOption) iter.Seq2[DirEntry, error] {
117 return func(yield func(DirEntry, error) bool) {
118 ctx, cancel := context.WithCancel(ctx)
119 defer cancel() // cancel Ls if done iterating early
120
121 dirs := make(chan DirEntry)
122 lsErr := make(chan error, 1)
123 go func() {
124 lsErr <- api.Ls(ctx, p, dirs, opts...)
125 }()
126 for dirEnt := range dirs {
127 if !yield(dirEnt, nil) {
128 return
129 }
130 }
131 if err := <-lsErr; err != nil {
132 yield(DirEntry{}, err)
133 }
134 }
135 }