final class LoadingContext { let content: Content var files: [String: FileResource] = [:] var pages: [String : Page] = [:] var tags: [String : Tag] = [:] var posts: [String : Post] = [:] var errors: Set = [] var tagOverview: TagOverview? var settings: Settings? init(content: Content) { self.content = content } func results() -> LoadingResult { .init( settings: settings ?? .default, posts: posts.values.sorted(ascending: false) { $0.startDate }, pages: pages.values.sorted(ascending: false) { $0.startDate }, tags: tags.values.sorted(), files: files.values.sorted { $0.id }, tagOverview: tagOverview, errors: errors.sorted()) } func error(_ message: String) { errors.insert(message) } func post(_ postId: String) -> Post? { if let post = posts[postId] { return post } error("Missing post \(postId)") return nil } func tag(_ tagId: String) -> Tag? { if let tag = tags[tagId] { return tag } error("Missing tag \(tagId)") return nil } func page(_ pageId: String) -> Page? { if let page = pages[pageId] { return page } error("Missing page \(pageId)") return nil } func file(_ fileId: String) -> FileResource? { if let file = files[fileId] { return file } error("Missing file \(fileId)") return nil } func image(_ imageId: String) -> FileResource? { guard let image = file(imageId) else { return nil } if image.type.isImage { return image } error("Image \(imageId) is not an image") return nil } func postMedia(_ imageId: String) -> FileResource? { guard let image = file(imageId) else { return nil } if image.type.isImage || image.type.isVideo { return image } error("Post Media \(imageId) is not an image or video") return nil } func item(itemId: ItemId) -> Item? { switch itemId.type { case .post: guard let id = itemId.id else { error("Missing post id in itemId") return nil } return post(id) case .page: guard let id = itemId.id else { error("Missing page id in itemId") return nil } return page(id) case .tag: guard let id = itemId.id else { error("Missing tag id in itemId") return nil } return tag(id) case .tagOverview: guard let tagOverview else { error("Missing tag overview") return nil } return tagOverview case .file: guard let id = itemId.id else { error("Missing file id in itemId") return nil } return file(id) } } }