Repository: CodeEditApp/CodeEdit
File: CodeEditModules/Modules/CodeFile/src/CodeFile.swift (Swift)

Code before:
//  CodeFile.swift
//  CodeEditModules/CodeFile
//
//  Created by Rehatbir Singh on 12/03/2022.
//

import AppKit
import Foundation
import SwiftUI
import UniformTypeIdentifiers
import QuickLookUI

public enum CodeFileError: Error {
    case failedToDecode
    case failedToEncode
    case fileTypeError
}

@objc(CodeFileDocument)
public final class CodeFileDocument: NSDocument, ObservableObject, QLPreviewItem {

    @Published
    var content = ""

    @Published
    var image: NSImage?

    /*
     This is the main type of the document.
     For example, if the file is end with '.png', it will be an image,
     if the file is end with '.py', it will be a text file.
     If text content is not empty, return text
     If its neither image or text, this could be nil.
    */
    public var typeOfFile: UTType? {
        if !self.content.isEmpty {
            return UTType.text
        }
        guard let fileType = fileType, let type = UTType(filenameExtension: fileType) else {
            return nil
        }
        if type.conforms(to: UTType.image) {
            return UTType.image
        }
        if type.conforms(to: UTType.text) {
            return UTType.text
        }
        return nil
    }

    /*

Review comment (suggestion):
I wonder about these two properties. Am I correct that both of them should not be set simultaneously? I can think only about the scenario where one is set, and the other is not. If my thinking is correct, we can consider merging them into one property. It can be achieved using `enum`, something like this: 
```
enum ContentType {
   case text(String)
   case image(NSImage)
}

@Published
var content: Content? // or var content: Content = .text("") 
```
Thanks to that solution API of this `class` is more consistent, and we are assured that an undefined state where `image` and `content` are set simultaneously. 

Code after:
//  CodeFile.swift
//  CodeEditModules/CodeFile
//
//  Created by Rehatbir Singh on 12/03/2022.
//

import AppKit
import Foundation
import SwiftUI
import UniformTypeIdentifiers
import QuickLookUI

public enum CodeFileError: Error {
    case failedToDecode
    case failedToEncode
    case fileTypeError
}

@objc(CodeFileDocument)
public final class CodeFileDocument: NSDocument, ObservableObject, QLPreviewItem {

    @Published
    var content = ""

    /*
     This is the main type of the document.
     For example, if the file is end with '.png', it will be an image,
     if the file is end with '.py', it will be a text file.
     If text content is not empty, return text
     If its neither image or text, this could be nil.
    */
    public var typeOfFile: UTType? {
        if !self.content.isEmpty {
            return UTType.text
        }
        guard let fileType = fileType, let type = UTType(filenameExtension: fileType) else {
            return nil
        }
        if type.conforms(to: UTType.image) {
            return UTType.image
        }
        if type.conforms(to: UTType.text) {
            return UTType.text
        }
        return nil
    }

    /*
     This is the QLPreviewItemURL
     */
    public var previewItemURL: URL? {