silk.system.glob_scan.
Find the files and directories that a glob pattern matches, by walking directories through
the FileSystem effect.
When to use#
Use scan to collect every match of a pattern such as src/**/*.silk, or a Walker to
take matches one at a time. To test paths you already have, use silk.text.glob directly.
Details#
A scan reads only the directories its pattern can reach. A literal segment is looked up
directly, a wildcard segment lists one directory, and ** descends into every directory
below. Results are relative to ScanOptions.base, joined with /, with . and ..
segments of the pattern resolved, and each one is reported once; the base itself is .. A
pattern that starts with / is scanned from the provider's root and reports absolute paths.
The order of results is unspecified.
Each segment is matched on its own, so a ! at the start of a segment negates that segment
only: !test/*.silk matches files in every directory except test. There is no
whole-pattern negation; to leave matches out, test the results with a silk.text.glob
pattern.
Names are host bytes and are reported as they are, also when they are not UTF-8.
A literal segment follows a symbolic link, so docs/*.md works when docs is a link to a
directory. A link that a wildcard matched is never entered, which also keeps a scan from
looping through a cycle of links; it is reported only when ScanOptions.onlyFiles is
false.
Every read goes through the FileSystem effect, so a scan sees exactly what the provider
shows, and a provider in memory or one that records reads works the same way.
Errors#
FileErrorif the starting directory is missing or is not a directory, or if the provider refuses a lookup or a listing, for example withPermissionDenied. An entry that is missing, is not a directory, or has a name no path can hold is not an error: it matches nothing.OutOfMemoryErrorfrom every operation that returns owned paths.
Examples#
Find the Silk sources of a project#
import silk.system.glob_scan { ScanOptions, scan }
import silk.system.filesystem { FileError, FileSystem, Path }
import silk.system.filesystem_native { OsFileSystem }
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.collections.bytes { Bytes }
import silk.collections.list { List }
import silk.core.effect { Effect }
effect fn program() -> i32 ! FileError | OutOfMemoryError ? &mut FileSystem | &mut Allocator {
let root = run Path.root()
let scratch = run FileSystem.temporaryDirectory(&root, "silk-glob-")
run FileSystem.writeFileWithParents(&run Path.join(&scratch.path, "src/main.silk"), b"")
run FileSystem.writeFileWithParents(&run Path.join(&scratch.path, "src/net/http.silk"), b"")
run FileSystem.writeFileWithParents(&run Path.join(&scratch.path, "README.md"), b"")
let options = run ScanOptions.make(&scratch.path)
let found = run scan("src/**/*.silk", move options)
let count = List<Bytes>.length(&found)
drop found
run FileSystem.release(move scratch)
if count != 2 {
return 1
}
return 0
}
effect fn failed<E>(error: E) -> i32 {
drop error
return 2
}
effect fn withFiles() -> i32 ! FileError | OutOfMemoryError ? &mut Allocator {
let mut files = run OsFileSystem.make("/tmp")
return run program() |> Effect.provideMut<FileSystem>(&mut files)
}
pub fn main() -> i32 {
let mut allocator = Allocator.systemAllocatorProvider()
return run Effect.catchAll(withFiles(), failed) |> Effect.provideMut<Allocator>(&mut allocator)
}Import as glob_scan with import silk.system.glob_scan as glob_scan.
Public declarations: 4.
ScanOptions#
pub struct ScanOptionsWhat a scan starts from and which entries it reports.
Field base#
pub base: PathThe directory relative patterns start from. Results are relative to it.
Field dot#
pub dot: boolWhether wildcards match names that start with .. A component that starts with a literal
. matches such names either way.
Field onlyFiles#
pub onlyFiles: boolWhether only regular files are reported. When false, directories and symbolic links that a wildcard matched are reported too.
Implementation ScanOptions#
impl ScanOptionsAssociated function make#
pub effect fn make(base: &Path) -> ScanOptions
! OutOfMemoryError
? &mut AllocatorOptions that scan from base, skip hidden names, and report regular files only.
Errors#
OutOfMemoryErrorif theAllocatorcannot copybase.
Walker#
pub struct WalkerA scan in progress: the directories still to read and the matches not yet returned.
Implementation Walker#
impl WalkerAssociated function make#
pub effect fn make(written: string, options: ScanOptions) -> Walker
! FileError | OutOfMemoryError
? &mut FileSystem | &mut AllocatorStarts a scan for the pattern written below options.base, or below the provider's root
when written starts with /.
Details#
Results are relative to options.base, joined with /, with . and .. segments of the
pattern resolved, and each path is reported once; the base itself is .. A pattern that
starts with / reports absolute paths. The order is unspecified.
The pattern is split at / into segments, and each directory is read only when a segment
can match below it: src/*.silk lists src and nothing else. Braces and groups work within
one segment. A / inside braces still splits the pattern, so {a/b,c} becomes the segments
{a and b,c}, which match those names literally. A ! at the start of a segment negates
that segment only. A pattern that ends with / reports directories only, and so reports
nothing while onlyFiles is set. An empty pattern reports nothing.
A literal segment follows a symbolic link, so a link it names counts as what it points to.
A link that a wildcard matched is never entered and is reported only when onlyFiles is
false.
Errors#
FileErrorif the starting directory does not exist or is not a directory, or if the provider refuses to look it up.OutOfMemoryErrorif theAllocatorcannot supply the walker.
Associated function makeBytes#
pub effect fn makeBytes(pattern: &[u8], options: ScanOptions) -> Walker
! FileError | OutOfMemoryError
? &mut FileSystem | &mut AllocatorStarts a scan for the host-byte pattern pattern, which need not be UTF-8, below
options.base, or below the provider's root when pattern starts with /.
Details#
Results are relative to options.base, joined with /, with . and .. segments of the
pattern resolved, and each path is reported once; the base itself is .. A pattern that
starts with / reports absolute paths. The order is unspecified.
The pattern is split at / into segments, and each directory is read only when a segment
can match below it: src/*.silk lists src and nothing else. Braces and groups work within
one segment. A / inside braces still splits the pattern, so {a/b,c} becomes the segments
{a and b,c}, which match those names literally. A ! at the start of a segment negates
that segment only. A pattern that ends with / reports directories only, and so reports
nothing while onlyFiles is set. An empty pattern reports nothing.
A literal segment follows a symbolic link, so a link it names counts as what it points to.
A link that a wildcard matched is never entered and is reported only when onlyFiles is
false.
Errors#
FileErrorif the starting directory does not exist or is not a directory, or if the provider refuses to look it up.OutOfMemoryErrorif theAllocatorcannot supply the walker.
Method next#
pub effect fn next(self: &mut Self) -> Option<Bytes>
! FileError | OutOfMemoryError
? &mut FileSystem | &mut AllocatorReturns the next match, or none once the scan is done.
Details#
A match is a path relative to the base, joined with /, or an absolute path for an absolute
pattern; the base itself is .. Each path is returned once, in unspecified order. Once it
returns none, it keeps returning none.
Errors#
FileErrorif the provider refuses to look up or list an entry the scan reaches, for example withPermissionDenied. An entry that is missing or is not a directory matches nothing instead.OutOfMemoryErrorif theAllocatorcannot supply a listing or a result.
Method collect#
pub effect fn collect(self: &mut Self) -> List<Bytes>
! FileError | OutOfMemoryError
? &mut FileSystem | &mut AllocatorReturns every match the scan has not returned yet, in unspecified order, as
Walker.next would return them one at a time.
Errors#
The errors of
Walker.next.
scan#
pub effect fn scan(pattern: string, options: ScanOptions) -> List<Bytes>
! FileError | OutOfMemoryError
? &mut FileSystem | &mut AllocatorReturns every path that pattern matches below options.base, in unspecified order.
Details#
Results are relative to options.base, joined with /, with . and .. segments of the
pattern resolved, and each path is reported once; the base itself is .. A pattern that
starts with / is scanned from the provider's root and reports absolute paths. Each segment is
matched on its own: a / inside braces still splits the pattern, and a ! at the start of a
segment negates that segment only. A literal segment follows a symbolic link; a link that a
wildcard matched is never entered and is reported only when onlyFiles is false.
Errors#
FileErrorif the starting directory does not exist or is not a directory, or if the provider refuses to look up or list an entry the scan reaches.OutOfMemoryErrorif theAllocatorcannot supply a listing or a result.
scanBytes#
pub effect fn scanBytes(pattern: &[u8], options: ScanOptions) -> List<Bytes>
! FileError | OutOfMemoryError
? &mut FileSystem | &mut AllocatorReturns every path that the host-byte pattern pattern, which need not be UTF-8, matches below
options.base, in unspecified order.
Details#
Results are relative to options.base, joined with /, with . and .. segments of the
pattern resolved, and each path is reported once; the base itself is .. A pattern that
starts with / is scanned from the provider's root and reports absolute paths. Each segment is
matched on its own: a / inside braces still splits the pattern, and a ! at the start of a
segment negates that segment only. A literal segment follows a symbolic link; a link that a
wildcard matched is never entered and is reported only when onlyFiles is false.
Errors#
FileErrorif the starting directory does not exist or is not a directory, or if the provider refuses to look up or list an entry the scan reaches.OutOfMemoryErrorif theAllocatorcannot supply a listing or a result.
Category: System.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, x86_64-pc-windows-msvc, wasm64-unknown-unknown.