From cd43efa11a478f1647ac9be5ad4598e481a85fb9 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Fri, 21 Mar 2025 20:11:05 +0800 Subject: [PATCH] Remove string concatenation in `Path#anchor` --- src/path.cr | 67 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/src/path.cr b/src/path.cr index 4ec62b39d95d..3b8b1e07a517 100644 --- a/src/path.cr +++ b/src/path.cr @@ -1122,7 +1122,10 @@ struct Path # # NOTE: Drives are only available for Windows paths. It can either be a drive letter (`C:`) or a UNC share (`\\host\share`). def drive : Path? - if drive = drive_and_root[0] + drive_end, _ = drive_and_root_indices + + if drive_end + drive = @name.byte_slice(0, drive_end) new_instance drive end end @@ -1138,7 +1141,11 @@ struct Path # Path.windows("\\\\host\\share\\folder").root # => Path.windows("\\") # ``` def root : Path? - if root = drive_and_root[1] + drive_end, root_end = drive_and_root_indices + + if root_end + root_start = drive_end || 0 + root = @name.byte_slice(root_start, root_end - root_start) new_instance root end end @@ -1152,47 +1159,49 @@ struct Path # Path.windows("\\\\host\\share\\folder").anchor # => Path.windows("\\\\host\\share\\") # ``` def anchor : Path? - drive, root = drive_and_root + drive_end, root_end = drive_and_root_indices + anchor_end = root_end || drive_end - if root - if drive - new_instance({drive, root}.join) - else - new_instance(root) - end - elsif drive - new_instance drive + if anchor_end + new_instance(@name.byte_slice(0, anchor_end)) end end # Returns a tuple of `#drive` and `#root` as strings. def drive_and_root : {String?, String?} + drive_end, root_end = drive_and_root_indices + + if drive_end + drive = @name.byte_slice(0, drive_end) + end + + if root_end + root_start = drive_end || 0 + root = @name.byte_slice(root_start, root_end - root_start) + end + + {drive, root} + end + + private def drive_and_root_indices : {Int32?, Int32?} if windows? if windows_drive? - drive = @name.byte_slice(0, 2) if separators.includes?(@name.byte_at?(2).try(&.chr)) - return drive, @name.byte_slice(2, 1) + {2, 3} else - return drive, nil + {2, nil} end elsif unc_share = unc_share? - share_end, root_end = unc_share - if share_end == root_end - root = nil - else - root = @name.byte_slice(share_end, root_end - share_end) - end - - return @name.byte_slice(0, share_end), root + unc_share elsif starts_with_separator? - return nil, @name.byte_slice(0, 1) + {nil, 1} else - return nil, nil + {nil, nil} end elsif absolute? # posix - return nil, "/" + {nil, 1} else - return nil, nil + {nil, nil} end end @@ -1261,7 +1270,11 @@ struct Path break unless separators.includes?(char) end - return share_end, reader.pos + unless reader.pos == share_end + root_end = reader.pos + end + + return share_end, root_end end # Returns `true` if this path is absolute.