///|
trait IsString {
to_string(Self) -> String
}
///|
pub impl IsString for StringView with to_string(self) = "%identity"
///|
pub impl IsString for String with to_string(self) = "%identity"
///|
pub impl IsString for WinPathComponent with to_string(self) = "%identity"
///|
pub impl IsString for UnixPathComponent with to_string(self) = "%identity"
///|
pub impl[A : IsString] Show for Directory[A] with output(self, logger) {
for component in self {
logger.write_string(component.to_string())
logger.write_char('/')
}
}
///|
pub impl Show for WinPathComponent with output(self, logger) {
logger.write_string(self.0)
}
///|
pub impl Show for WinPathComponent with to_string(self) = "%identity"
///|
pub impl Show for UnixPathComponent with output(self, logger) {
logger.write_string(self.0)
}
///|
pub impl Show for UnixPathComponent with to_string(self) = "%identity"
///|
pub impl[A : IsString] Show for File[A] with output(self, logger) {
logger.write_string(self.base.to_string())
if self.extension is Some(ext) {
logger.write_char('.')
logger.write_string(ext.to_string())
}
}
///|
const VerbatimPrefix : String =
#|\\?\
///|
const VerbatimUncPrefix : String =
#|\\?\UNC\
///|
const ColonBackslash : String =
#|:\
///|
const VolumePrefix : String =
#|\\?\Volume{
///|
const VolumeSuffix : String =
#|}
///|
const DevicePrefix : String =
#|\\.\
///|
const UncPrefix : String =
#|\\
///|
const BackSlash : Char = '\\'
///|
pub impl Show for WinPrefix with output(self, logger) {
match self {
Root => logger.write_char(BackSlash)
VerbatimSymlink(symlink~) => {
logger.write_string(VerbatimPrefix)
logger.write_string(symlink)
logger.write_char(BackSlash)
}
VerbatimUNC(hostname~, shared_folder~) => {
logger.write_string(VerbatimUncPrefix)
logger.write_string(hostname)
logger.write_char(BackSlash)
logger.write_string(shared_folder)
logger.write_char(BackSlash)
}
VerbatimVolumeLetter(letter) => {
logger.write_string(VerbatimPrefix)
logger.write_char(letter)
logger.write_string(ColonBackslash)
}
VerbatimVolumeGUID(guid) => {
logger.write_string(VolumePrefix)
logger.write_string(guid)
logger.write_string(VolumeSuffix)
}
DeviceNS(device~) => {
logger.write_string(DevicePrefix)
logger.write_string(device)
logger.write_char(BackSlash)
}
UNC(hostname~, shared_folder~) => {
logger.write_string(UncPrefix)
logger.write_string(hostname)
logger.write_char(BackSlash)
logger.write_string(shared_folder)
logger.write_char(BackSlash)
}
VolumeLetter(letter) => {
logger.write_char(letter)
logger.write_string(ColonBackslash)
}
None => ()
}
}
///|
pub impl Show for WinPath with output(self, logger) {
let { prefix, directory, file } = self
logger.write_object(prefix)
for component in directory {
logger.write_object(component)
logger.write_char(BackSlash)
}
if file is Some(file) {
logger.write_object(file)
}
}
///|
const Slash = '/'
///|
pub impl Show for UnixPath with output(self, logger) {
let { is_absolute, directory, file } = self
if is_absolute {
logger.write_char(Slash)
}
for component in directory {
logger.write_object(component)
logger.write_char(Slash)
}
if file is Some(file) {
logger.write_object(file)
}
}
///|
pub impl Show for Path with output(self, logger) {
match self {
UPath(path) => logger.write_object(path)
WPath(path) => logger.write_object(path)
}
}
///|
pub impl Show for PathBuilder with output(self, logger) {
match self {
{ prefix: Some(prefix), directory, basename, extension, .. } => {
// windows style
logger.write_object(prefix)
for component in directory {
logger.write_string(component)
logger.write_char(BackSlash)
}
if basename is Some(b) {
logger.write_string(b)
if extension is Some(ext) {
logger.write_char('.')
logger.write_string(ext)
}
}
}
{ prefix: None, is_absolute, directory, basename, extension } => {
// unix style
if is_absolute {
logger.write_char(Slash)
}
for component in directory {
logger.write_string(component)
logger.write_char(Slash)
}
if basename is Some(b) {
logger.write_string(b)
if extension is Some(ext) {
logger.write_char('.')
logger.write_string(ext)
}
}
}
}
}
///|
test "unix path" {
let path = UnixPath::new(directory=Directory::new(["username", ".moon"]))
inspect(path, content="username/.moon/")
let path = UnixPath::new(
is_absolute=true,
directory=Directory::new(["home", "username", ".moon"]),
)
inspect(path, content="/home/username/.moon/")
let path = UnixPath::new(directory=Directory::new([]))
inspect(path, content="")
let path = UnixPath::new(is_absolute=true, directory=Directory::new([]))
inspect(path, content="/")
}
///|
test "windows path" {
let path = WinPath::new(
prefix=VolumeLetter('C'),
directory=Directory::new(["Users", "username", "Documents"]),
file=File::new(base="file", extension="txt"),
)
inspect(path, content="C:\\Users\\username\\Documents\\file.txt")
let path = WinPath::new(directory=Directory::new(["develop", "my_project"]))
inspect(path, content="develop\\my_project\\")
let path = WinPath::new(
directory=Directory::new(["develop", "my_project"]),
file=File::new(base="readme", extension="md"),
)
inspect(path, content="develop\\my_project\\readme.md")
let path = WinPath::new(
prefix=UNC(hostname="server", shared_folder="share"),
directory=Directory::new(["folder"]),
)
inspect(path, content="\\\\server\\share\\folder\\")
let path = WinPath::new(
prefix=VerbatimUNC(hostname="server", shared_folder="share"),
directory=Directory::new(["folder"]),
)
inspect(path, content="\\\\?\\UNC\\server\\share\\folder\\")
let path = WinPath::new(
prefix=VerbatimVolumeLetter('D'),
directory=Directory::new(["Pictures"]),
file=File::new(base="apple", extension="png"),
)
inspect(path, content="\\\\?\\D:\\Pictures\\apple.png")
let path = WinPath::new(
prefix=VerbatimVolumeGUID("12345678-1234-1234-1234-1234567890AB"),
directory=Directory::new(["folder"]),
)
inspect(
path,
content="\\\\?\\Volume{12345678-1234-1234-1234-1234567890AB}folder\\",
)
let path = WinPath::new(
prefix=DeviceNS(device="COM56"),
directory=Directory::new(["folder"]),
)
inspect(path, content="\\\\.\\COM56\\folder\\")
}