import Foundation enum FileTypeCategory: String, CaseIterable { case image case code case model case text case video case resource case asset case audio var text: String { switch self { case .image: return "Images" case .code: return "Code" case .model: return "Models" case .text: return "Text" case .video: return "Videos" case .asset: return "Assets" case .resource: return "Other" case .audio: return "Audio" } } } extension FileTypeCategory: Hashable { } extension FileTypeCategory: Identifiable { var id: String { rawValue } } enum FileType: String { // MARK: Images case jpg case png case avif case webp case gif case svg case tiff // MARK: Code case html case cpp case swift // MARK: Assets case css case js case ttf case ico // MARK: Text case json case conf case yaml case txt // MARK: Model case stl case f3d case step case glb case f3z // MARK: Video case mp4 case m4v case webm // MARK: Audio case mp3 case aac case m4b case m4a // MARK: Other case noExtension case zip case cddx case pdf case key case psd // MARK: Unknown case unknown init(fileExtension: String?) { guard let lower = fileExtension?.lowercased() else { self = .noExtension return } if lower == "jpeg" { self = .jpg return } guard let type = FileType(rawValue: lower) else { self = .unknown return } self = type } var category: FileTypeCategory { switch self { case .jpg, .png, .avif, .webp, .gif, .svg, .tiff: return .image case .mp4, .m4v, .webm: return .video case .mp3, .aac, .m4b, .m4a: return .audio case .js, .css, .ttf, .ico: return .asset case .json, .conf, .yaml, .txt: return .text case .html, .cpp, .swift: return .code case .stl, .f3d, .step, .glb, .f3z: return .model case .zip, .cddx, .pdf, .key, .psd: return .resource case .noExtension, .unknown: return .resource } } var fileExtension: String? { switch self { case .noExtension, .unknown: return nil default: return rawValue } } var isImage: Bool { category == .image } var isVideo: Bool { category == .video } var isAudio: Bool { category == .audio } var isAsset: Bool { category == .asset } var isTextFile: Bool { switch category { case .text, .code: return true default: break } switch self { case .css, .js: return true default: return false } } var htmlType: String? { switch self { case .mp4, .m4v: return "video/mp4" case .webm: return "video/webm" default: return nil } } }