Skip to content

Commit 59164eb

Browse files
add readdirx which returns more object info
1 parent 3ed2b49 commit 59164eb

File tree

2 files changed

+61
-5
lines changed

2 files changed

+61
-5
lines changed

base/exports.jl

+1
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,7 @@ export
865865
readbytes!,
866866
readchomp,
867867
readdir,
868+
readdirx,
868869
readline,
869870
readlines,
870871
readuntil,

base/file.jl

+60-5
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export
1919
rename,
2020
readlink,
2121
readdir,
22+
readdirx,
2223
rm,
2324
samefile,
2425
sendfile,
@@ -29,6 +30,8 @@ export
2930
unlink,
3031
walkdir
3132

33+
import Base.==
34+
3235
# get and set current directory
3336

3437
"""
@@ -913,7 +916,56 @@ julia> readdir(abspath("base"), join=true)
913916
"/home/JuliaUser/dev/julia/base/weakkeydict.jl"
914917
```
915918
"""
916-
function readdir(dir::AbstractString; join::Bool=false, sort::Bool=true)
919+
readdir(; join::Bool=false, kwargs...) = readdir(join ? pwd() : "."; join, kwargs...)::Vector{String}
920+
readdir(dir::AbstractString; kwargs...) = _readdir(dir; return_objects=false, kwargs...)::Vector{String}
921+
922+
# this might be better as an Enum but they're not available here
923+
# UV_DIRENT_T
924+
const UV_DIRENT_UNKNOWN = Cint(0)
925+
const UV_DIRENT_FILE = Cint(1)
926+
const UV_DIRENT_DIR = Cint(2)
927+
const UV_DIRENT_LINK = Cint(3)
928+
const UV_DIRENT_FIFO = Cint(4)
929+
const UV_DIRENT_SOCKET = Cint(5)
930+
const UV_DIRENT_CHAR = Cint(6)
931+
const UV_DIRENT_BLOCK = Cint(7)
932+
struct FileKind
933+
dir::String
934+
name::String
935+
rawtype::Cint
936+
end
937+
function Base.getproperty(obj::FileKind, p::Symbol)
938+
if p == :path
939+
return joinpath(obj.dir, obj.name)
940+
else
941+
return getfield(obj, p)
942+
end
943+
end
944+
Base.isless(a::FileKind, b::FileKind) = isless(a.name, b.name)
945+
==(a::FileKind, b::FileKind) = a.name == b.name
946+
==(a::AbstractString, b::FileKind) = a == b.name
947+
==(a::FileKind, b::AbstractString) = b == a
948+
joinpath(obj::FileKind, args...) = joinpath(obj.path, args...)
949+
Base.convert(::Type{String}, obj::FileKind) = obj.name
950+
isunknown(obj::FileKind) = obj.rawtype == UV_DIRENT_UNKNOWN
951+
islink(obj::FileKind) = isunknown(obj) ? islink(obj.path) : obj.rawtype == UV_DIRENT_LINK
952+
isfile(obj::FileKind) = (isunknown(obj) || islink(obj)) ? isfile(obj.path) : obj.rawtype == UV_DIRENT_FILE
953+
isdir(obj::FileKind) = (isunknown(obj) || islink(obj)) ? isdir(obj.path) : obj.rawtype == UV_DIRENT_DIR
954+
isfifo(obj::FileKind) = (isunknown(obj) || islink(obj)) ? isfifo(obj.path) : obj.rawtype == UV_DIRENT_FIFO
955+
issocket(obj::FileKind) = (isunknown(obj) || islink(obj)) ? issocket(obj.path) : obj.rawtype == UV_DIRENT_SOCKET
956+
ischardev(obj::FileKind) = (isunknown(obj) || islink(obj)) ? ischardev(obj.path) : obj.rawtype == UV_DIRENT_CHAR
957+
isblockdev(obj::FileKind) = (isunknown(obj) || islink(obj)) ? isblockdev(obj.path) : obj.rawtype == UV_DIRENT_BLOCK
958+
959+
"""
960+
readdirx(dir::AbstractString=pwd();
961+
join::Bool = false,
962+
sort::Bool = true,
963+
) -> Vector{FileKind}
964+
"""
965+
readdirx(; join::Bool=false, kwargs...) = readdirx(join ? pwd() : "."; join, kwargs...)::Vector{FileKind}
966+
readdirx(dir::AbstractString; kwargs...) = _readdir(dir; return_objects=true, kwargs...)::Vector{FileKind}
967+
968+
function _readdir(dir::AbstractString; return_objects::Bool=false, join::Bool=false, sort::Bool=true)
917969
# Allocate space for uv_fs_t struct
918970
req = Libc.malloc(_sizeof_uv_fs)
919971
try
@@ -923,11 +975,16 @@ function readdir(dir::AbstractString; join::Bool=false, sort::Bool=true)
923975
err < 0 && uv_error("readdir($(repr(dir)))", err)
924976

925977
# iterate the listing into entries
926-
entries = String[]
978+
entries = return_objects ? FileKind[] : String[]
927979
ent = Ref{uv_dirent_t}()
928980
while Base.UV_EOF != ccall(:uv_fs_scandir_next, Cint, (Ptr{Cvoid}, Ptr{uv_dirent_t}), req, ent)
929981
name = unsafe_string(ent[].name)
930-
push!(entries, join ? joinpath(dir, name) : name)
982+
if return_objects
983+
rawtype = ent[].typ
984+
push!(entries, FileKind(dir, name, rawtype))
985+
else
986+
push!(entries, join ? joinpath(dir, name) : name)
987+
end
931988
end
932989

933990
# Clean up the request string
@@ -941,8 +998,6 @@ function readdir(dir::AbstractString; join::Bool=false, sort::Bool=true)
941998
Libc.free(req)
942999
end
9431000
end
944-
readdir(; join::Bool=false, sort::Bool=true) =
945-
readdir(join ? pwd() : ".", join=join, sort=sort)
9461001

9471002
"""
9481003
walkdir(dir; topdown=true, follow_symlinks=false, onerror=throw)

0 commit comments

Comments
 (0)