Last active
March 3, 2021 09:12
-
-
Save hoonsubin/d8facc63d5229885e96295f24d56242a to your computer and use it in GitHub Desktop.
A simple utility to create a full path from the given point with all the directory change
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.IO; | |
using System; | |
namespace HoonKim.Editor | |
{ | |
public static class UnityPathUtil | |
{ | |
/// <summary> | |
/// Path utility that combines the original path with the relative path with all the directory change operations. | |
/// This is a simple implementation focusing on readability, but we can expand this class to do more. | |
/// </summary> | |
/// <param name="originPath">The reference path</param> | |
/// <param name="relativeTarget">Relative path from the origin path</param> | |
/// <param name="separator">File separator. Default is the Unix style</param> | |
/// <returns>The full path to the given relative path</returns> | |
public static string GetFullPathFromRelative(string originPath, string relativeTarget, char separator = '/') | |
{ | |
// note: we assume the root is `Assets/` as that is the default for the editor | |
// if you want this to work for different platforms and in runtime, you can use the | |
string[] sourceFolders = originPath.Split(separator); | |
string[] destFolders = relativeTarget.Split(separator); | |
// ensure that the provided relative target is not an absolute path | |
if (destFolders[0] != "." && destFolders[0] != "..") | |
{ | |
throw new Exception($"{relativeTarget} is not a relative path"); | |
} | |
// directories are easier to work as a stack | |
Stack<string> fullPathStack = new Stack<string>(sourceFolders); | |
for (int i = sourceFolders.Length - 1; i >= 0; i--) | |
{ | |
if (string.IsNullOrEmpty(sourceFolders[i]) || Path.HasExtension(sourceFolders[i])) | |
{ | |
// change all the folders as an array and remove any empty elements (in case of a leading `/` to denote that it's a folder) | |
fullPathStack.Pop(); | |
} | |
else | |
{ | |
// if the path is valid, | |
break; | |
} | |
} | |
for (int i = 0; i < destFolders.Length; i++) | |
{ | |
string currentFolder = destFolders[i]; | |
if (currentFolder == "..") | |
{ | |
// go up one level | |
fullPathStack.Pop(); | |
} | |
else if (currentFolder == ".") | |
{ | |
continue; | |
} | |
// checking for empty elements for corner cases | |
else if (!string.IsNullOrEmpty(currentFolder)) | |
{ | |
// add the current folder | |
fullPathStack.Push(currentFolder); | |
} | |
} | |
// Stack.ToArray() method is LIFO of the elements, so we need to flip it | |
// note: the Array.Reverse() function mutates the passed array instead of returning a new one | |
string[] fullPathArray = fullPathStack.ToArray(); | |
Array.Reverse(fullPathArray); | |
return String.Join(separator.ToString(), fullPathArray); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment