From 40dca11c1230ea095efe929dfc462dad18bf4ccd Mon Sep 17 00:00:00 2001 From: Manish Meganathan Date: Mon, 8 Aug 2022 04:47:42 +0530 Subject: [PATCH] Implement FilePath Creation from Elements - Implemented NewFilePath constructor for creating the FilePath from a given variadic set of path elements. #3 - Added docs for Root() and FilePath --- filepath.go | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/filepath.go b/filepath.go index ec735e4..27248db 100644 --- a/filepath.go +++ b/filepath.go @@ -1,16 +1,67 @@ package moibit +import ( + "fmt" + "strings" +) + +// FilePath represents the path to a file/directory in MOIBit. type FilePath struct { elements []string extension string } +// Root returns a FilePath object that points to file system root i.e "/" func Root() FilePath { return FilePath{} } +// NewFilePath generates a new FilePath from a given variadic set of path elements. +// Each path element represents one level on the file system as a directory +// and can contain any character except for periods (.) and slashes (/). +// +// The last element may contain a single period to represent a file with a name and an extension like +// "file.json" or "hello.txt". If the last element has no period, the path is constructed for a directory +// +// An error is returned if any path element is invalid by not satisfying the above conditions. +// If no elements are given, the returned FilePath references the root directory. func NewFilePath(elements ...string) (FilePath, error) { - return FilePath{}, nil + // Create a FilePath with initialized elements slice + fp := FilePath{make([]string, 0, len(elements)), ""} + + // Iterate through the elements + for idx, element := range elements { + // If the element contains slash (/), throw an error + if strings.Contains(element, "/") { + return Root(), fmt.Errorf("failed to construct filepath: element '%v' contains slash", idx) + } + + // If the element contains period (.) + if strings.Contains(element, ".") { + // Check if element is the last one + if idx == len(element)-1 { + // Split the element along the period and check if it contains only 2 split elements + split := strings.Split(element, ".") + if len(split) != 2 { + return Root(), fmt.Errorf("failed to construct filepath: last element contains multiple periods") + } + + // Append the first split element into the fp elements (file name) + fp.elements = append(fp.elements, split[0]) + // Set the file second split element as file extension + fp.extension = split[1] + continue + } + + // Throw error for non-final element with period (.) + return Root(), fmt.Errorf("failed to construct filepath: non-final element '%v' contains period", idx) + } + + // Append the element into the fp elements + fp.elements = append(fp.elements, element) + } + + return fp, nil } func NewFilePathFromString(path string) (FilePath, error) {