import { EntryType, PushStatus, ReadStatus, Permissions } from "./enum" import { Entry, EntryCollection, FileInner, EntryFile, EntryCollectionManipulate, EntryFileInner } from "./types/entry" import directory_search from "./index" import { wrap_entry, wrap_none, WrapResultEntry, WrapResultNone } from "./wrap" interface Rfwfs { directory: (name: string, permissions: Permissions, timestamp: number, inner_default: T[]) => EntryCollection, is_file: (entry: T) => boolean, is_dir: (entry: T) => boolean, file: (name: string, permissions: Permissions, timestamp: number, inner_default: FileInner) => EntryFile, } function read_write_access(permissions: Permissions): boolean { return permissions === Permissions.rw } function read_access(permissions: Permissions): boolean { return read_write_access(permissions) || permissions === Permissions.r } function write_access(permissions: Permissions): boolean { return read_write_access(permissions) || permissions === Permissions.w } function directory_sort(self: EntryCollectionManipulate) { self.__body.sort((a,z) => a.name.localeCompare(z.name)) } function directory_push(self: EntryCollection, entry: E): WrapResultNone { if (write_access(self.permissions)) { const no_duplicates = directory_search(self.inner.__body, entry.name) if (!no_duplicates) { self.inner.__body.push(entry) self.inner.__body.sort() return wrap_none(PushStatus.Ok) } return wrap_none(PushStatus.Duplicate) } return wrap_none(PushStatus.Denied) } function directory_find(self: EntryCollection, file_name: string): WrapResultEntry { if (read_access(self.permissions)) { const file_search = directory_search(self.inner.__body, file_name) if (file_search) { return wrap_entry(ReadStatus.Ok, file_search.result) } return wrap_entry(ReadStatus.NotFound) } return wrap_entry(ReadStatus.Denied) } function directory_pop(self: EntryCollection, file_name: string): WrapResultEntry { if (read_write_access(self.permissions)) { const pop_find = directory_search(self.inner.__body, file_name) if (pop_find) { self.inner.__body.splice(pop_find.some, 1) return wrap_entry(ReadStatus.Ok, pop_find.result) } return wrap_entry(ReadStatus.NotFound) } return wrap_entry(ReadStatus.Denied) } function file_inner_read(self: EntryFileInner, permissions: Permissions): FileInner | undefined { return read_access(permissions) ? self.__body : undefined } function file_inner_write(self: EntryFileInner, permissions: Permissions, item: FileInner): boolean { if (write_access(permissions)) { self.__body = item return true } return false } function file_inner(permissions: Permissions, inner_default: FileInner): EntryFileInner { const file_inner_trait = { __body: inner_default } as EntryFileInner file_inner_trait.read = function() { return file_inner_read(this, permissions) } file_inner_trait.write = function(item) { return file_inner_write(this, permissions, item) } return file_inner_trait } function dir_inner(self: EntryCollection, collection: T[]): EntryCollectionManipulate { const collection_trait = { __body: collection } as EntryCollectionManipulate collection_trait.pop = function(file_name) { return directory_pop(self, file_name) } collection_trait.find = function(file_name) { return directory_find(self, file_name) } collection_trait.push = function(entry) { return directory_push(self, entry) } collection_trait.sort = function() { return directory_sort(this) } collection_trait.sort() //the default collection is automatically sorted on directory creation. return collection_trait } const rfwfs = {} as Rfwfs rfwfs.is_dir = function(entry) { return entry.type === EntryType.Directory } rfwfs.is_file = function(entry) { return entry.type === EntryType.File } rfwfs.file = function(name, permissions, timestamp, inner_default) { const file = { type: EntryType.File } as EntryFile file.permissions = permissions file.timestamp = timestamp file.inner = file_inner(permissions, inner_default) file.name = name file.hash = "0" return file } rfwfs.directory = function(name: string, permissions: Permissions, timestamp: number, inner_default: T[]): EntryCollection { const directory = { type: EntryType.Directory } as EntryCollection directory.permissions = permissions directory.timestamp = timestamp directory.inner = dir_inner(directory, inner_default) directory.name = name return directory } export default rfwfs