final class ModelLoader { let content: Content let storage: Storage let context: LoadingContext init(content: Content, storage: Storage) { self.content = content self.storage = storage self.context = .init(content: content) } func load() -> LoadingResult { loadInternal() return context.results() } private func loadInternal() { guard storage.contentScope != nil else { context.error("Storage not initialized, not loading content") return } loadFiles() loadTags() loadPages() loadPosts() loadSettings() } private func loadFiles() { guard let files = storage.loadAllFiles() else { context.error("Failed to load file list") return } if files.isEmpty { print("No files loaded") } files.forEach { (fileId, data) in let fileData = data.data let isExternal = data.isExternal context.files[fileId] = FileResource(content: content, id: fileId, data: fileData, isExternalFile: isExternal) } } private func loadTags() { guard let tags = storage.loadAllTags() else { context.error("Failed to load file tags") return } if tags.isEmpty { print("No tags loaded") } tags.forEach { (tagId, data) in context.tags[tagId] = Tag(context: context, id: tagId, data: data) } } private func loadPages() { guard let pages = storage.loadAllPages() else { context.error("Failed to load file pages") return } if pages.isEmpty { print("No pages loaded") } pages.forEach { pageId, data in let page = Page(context: context, id: pageId, data: data) page.updateContentExistence() context.pages[pageId] = page } } private func loadPosts() { guard let posts = storage.loadAllPosts() else { context.error("Failed to load file posts") return } if posts.isEmpty { print("No posts loaded") } posts.forEach { postId, data in context.posts[postId] = Post(context: context, id: postId, data: data) } } private func loadSettings() { guard let settings = storage.loadSettings() else { context.error("Failed to load settings") return } context.tagOverview = settings.tagOverview.map { data in TagOverview(context: context, id: "all-tags", data: data) } context.settings = Settings(context: context, data: settings) } }