Переглянути джерело

Fix WordLimit scope errors by moving helpers into String+WordCount.

Consolidating word-limit logic into the String extension avoids Xcode indexer failures that left ViewModels unable to resolve the separate WordLimit type.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 1 місяць тому
батько
коміт
7ba82d5db9

+ 19 - 0
gramora/Utilities/String+WordCount.swift

@@ -35,4 +35,23 @@ extension String {
 
         return self
     }
+
+    static func wordLimitExceededMessage(maxWords: Int) -> String {
+        "Maximum \(maxWords) words allowed."
+    }
+
+    func applyingWordLimit(maxWords: Int) -> (text: String, exceeded: Bool) {
+        guard wordCount > maxWords else { return (self, false) }
+        return (truncated(toMaxWords: maxWords), true)
+    }
+
+    static func importedApplyingWordLimit(
+        _ text: String,
+        maxWords: Int,
+        setError: (String?) -> Void
+    ) -> String {
+        let (limited, exceeded) = text.applyingWordLimit(maxWords: maxWords)
+        setError(exceeded ? wordLimitExceededMessage(maxWords: maxWords) : nil)
+        return limited
+    }
 }

+ 0 - 22
gramora/Utilities/WordLimit.swift

@@ -1,22 +0,0 @@
-import Foundation
-
-enum WordLimit {
-    static func message(maxWords: Int) -> String {
-        "Maximum \(maxWords) words allowed."
-    }
-
-    static func apply(_ text: String, maxWords: Int) -> (text: String, exceeded: Bool) {
-        guard text.wordCount > maxWords else { return (text, false) }
-        return (text.truncated(toMaxWords: maxWords), true)
-    }
-
-    static func applyImported(
-        _ text: String,
-        maxWords: Int,
-        setError: (String?) -> Void
-    ) -> String {
-        let (limited, exceeded) = apply(text, maxWords: maxWords)
-        setError(exceeded ? message(maxWords: maxWords) : nil)
-        return limited
-    }
-}

+ 5 - 5
gramora/ViewModels/EmailWriterViewModel.swift

@@ -39,20 +39,20 @@ final class EmailWriterViewModel: ObservableObject {
 
     func pastePrompt() {
         guard let clipboard = NSPasteboard.general.string(forType: .string) else { return }
-        prompt = WordLimit.applyImported(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+        prompt = String.importedApplyingWordLimit(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
         generatedEmail = ""
     }
 
     func notifyWordLimitReached() {
-        errorMessage = WordLimit.message(maxWords: Self.maxWords)
+        errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
     }
 
     func handlePromptChange() {
-        let (limited, exceeded) = WordLimit.apply(prompt, maxWords: Self.maxWords)
+        let (limited, exceeded) = prompt.applyingWordLimit(maxWords: Self.maxWords)
         if exceeded {
             prompt = limited
-            errorMessage = WordLimit.message(maxWords: Self.maxWords)
-        } else if errorMessage == WordLimit.message(maxWords: Self.maxWords) {
+            errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
+        } else if errorMessage == String.wordLimitExceededMessage(maxWords: Self.maxWords) {
             errorMessage = nil
         }
         if !generatedEmail.isEmpty {

+ 6 - 6
gramora/ViewModels/GrammarCheckerViewModel.swift

@@ -42,7 +42,7 @@ final class GrammarCheckerViewModel: ObservableObject {
 
     func pasteText() {
         guard let clipboard = NSPasteboard.general.string(forType: .string) else { return }
-        text = WordLimit.applyImported(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+        text = String.importedApplyingWordLimit(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
         resetResults()
     }
 
@@ -50,7 +50,7 @@ final class GrammarCheckerViewModel: ObservableObject {
         Task {
             do {
                 guard let extracted = try await textExtractionService.pickAndExtractText() else { return }
-                text = WordLimit.applyImported(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+                text = String.importedApplyingWordLimit(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
                 resetResults()
             } catch {
                 errorMessage = error.localizedDescription
@@ -59,15 +59,15 @@ final class GrammarCheckerViewModel: ObservableObject {
     }
 
     func notifyWordLimitReached() {
-        errorMessage = WordLimit.message(maxWords: Self.maxWords)
+        errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
     }
 
     func handleTextChange() {
-        let (limited, exceeded) = WordLimit.apply(text, maxWords: Self.maxWords)
+        let (limited, exceeded) = text.applyingWordLimit(maxWords: Self.maxWords)
         if exceeded {
             text = limited
-            errorMessage = WordLimit.message(maxWords: Self.maxWords)
-        } else if errorMessage == WordLimit.message(maxWords: Self.maxWords) {
+            errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
+        } else if errorMessage == String.wordLimitExceededMessage(maxWords: Self.maxWords) {
             errorMessage = nil
         }
         if hasResults {

+ 5 - 5
gramora/ViewModels/JournalFinderViewModel.swift

@@ -54,20 +54,20 @@ final class JournalFinderViewModel: ObservableObject {
 
     func pasteAbstract() {
         guard let clipboard = NSPasteboard.general.string(forType: .string) else { return }
-        abstractText = WordLimit.applyImported(clipboard, maxWords: Self.maxAbstractWords, setError: { errorMessage = $0 })
+        abstractText = String.importedApplyingWordLimit(clipboard, maxWords: Self.maxAbstractWords, setError: { errorMessage = $0 })
         resetResults()
     }
 
     func notifyAbstractWordLimitReached() {
-        errorMessage = WordLimit.message(maxWords: Self.maxAbstractWords)
+        errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxAbstractWords)
     }
 
     func handleAbstractTextChange() {
-        let (limited, exceeded) = WordLimit.apply(abstractText, maxWords: Self.maxAbstractWords)
+        let (limited, exceeded) = abstractText.applyingWordLimit(maxWords: Self.maxAbstractWords)
         if exceeded {
             abstractText = limited
-            errorMessage = WordLimit.message(maxWords: Self.maxAbstractWords)
-        } else if errorMessage == WordLimit.message(maxWords: Self.maxAbstractWords) {
+            errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxAbstractWords)
+        } else if errorMessage == String.wordLimitExceededMessage(maxWords: Self.maxAbstractWords) {
             errorMessage = nil
         }
         if hasResults {

+ 6 - 6
gramora/ViewModels/LanguageTranslatorViewModel.swift

@@ -45,7 +45,7 @@ final class LanguageTranslatorViewModel: ObservableObject {
 
     func pasteText() {
         guard let clipboard = NSPasteboard.general.string(forType: .string) else { return }
-        sourceText = WordLimit.applyImported(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+        sourceText = String.importedApplyingWordLimit(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
         translatedText = ""
     }
 
@@ -53,7 +53,7 @@ final class LanguageTranslatorViewModel: ObservableObject {
         Task {
             do {
                 guard let extracted = try await textExtractionService.pickAndExtractText() else { return }
-                sourceText = WordLimit.applyImported(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+                sourceText = String.importedApplyingWordLimit(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
                 translatedText = ""
             } catch {
                 errorMessage = error.localizedDescription
@@ -62,15 +62,15 @@ final class LanguageTranslatorViewModel: ObservableObject {
     }
 
     func notifyWordLimitReached() {
-        errorMessage = WordLimit.message(maxWords: Self.maxWords)
+        errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
     }
 
     func handleSourceTextChange() {
-        let (limited, exceeded) = WordLimit.apply(sourceText, maxWords: Self.maxWords)
+        let (limited, exceeded) = sourceText.applyingWordLimit(maxWords: Self.maxWords)
         if exceeded {
             sourceText = limited
-            errorMessage = WordLimit.message(maxWords: Self.maxWords)
-        } else if errorMessage == WordLimit.message(maxWords: Self.maxWords) {
+            errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
+        } else if errorMessage == String.wordLimitExceededMessage(maxWords: Self.maxWords) {
             errorMessage = nil
         }
         if !translatedText.isEmpty {

+ 6 - 6
gramora/ViewModels/ParaphrasingViewModel.swift

@@ -36,7 +36,7 @@ final class ParaphrasingViewModel: ObservableObject {
 
     func pasteText() {
         guard let clipboard = NSPasteboard.general.string(forType: .string) else { return }
-        text = WordLimit.applyImported(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+        text = String.importedApplyingWordLimit(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
         paraphrasedText = ""
     }
 
@@ -44,7 +44,7 @@ final class ParaphrasingViewModel: ObservableObject {
         Task {
             do {
                 guard let extracted = try await textExtractionService.pickAndExtractText() else { return }
-                text = WordLimit.applyImported(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+                text = String.importedApplyingWordLimit(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
                 paraphrasedText = ""
             } catch {
                 errorMessage = error.localizedDescription
@@ -53,15 +53,15 @@ final class ParaphrasingViewModel: ObservableObject {
     }
 
     func notifyWordLimitReached() {
-        errorMessage = WordLimit.message(maxWords: Self.maxWords)
+        errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
     }
 
     func handleTextChange() {
-        let (limited, exceeded) = WordLimit.apply(text, maxWords: Self.maxWords)
+        let (limited, exceeded) = text.applyingWordLimit(maxWords: Self.maxWords)
         if exceeded {
             text = limited
-            errorMessage = WordLimit.message(maxWords: Self.maxWords)
-        } else if errorMessage == WordLimit.message(maxWords: Self.maxWords) {
+            errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
+        } else if errorMessage == String.wordLimitExceededMessage(maxWords: Self.maxWords) {
             errorMessage = nil
         }
         if !paraphrasedText.isEmpty {

+ 6 - 6
gramora/ViewModels/PunctuationCheckerViewModel.swift

@@ -34,7 +34,7 @@ final class PunctuationCheckerViewModel: ObservableObject {
 
     func pasteText() {
         guard let clipboard = NSPasteboard.general.string(forType: .string) else { return }
-        text = WordLimit.applyImported(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+        text = String.importedApplyingWordLimit(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
         resetResults()
     }
 
@@ -42,7 +42,7 @@ final class PunctuationCheckerViewModel: ObservableObject {
         Task {
             do {
                 guard let extracted = try await textExtractionService.pickAndExtractText() else { return }
-                text = WordLimit.applyImported(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+                text = String.importedApplyingWordLimit(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
                 resetResults()
             } catch {
                 errorMessage = error.localizedDescription
@@ -51,15 +51,15 @@ final class PunctuationCheckerViewModel: ObservableObject {
     }
 
     func notifyWordLimitReached() {
-        errorMessage = WordLimit.message(maxWords: Self.maxWords)
+        errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
     }
 
     func handleTextChange() {
-        let (limited, exceeded) = WordLimit.apply(text, maxWords: Self.maxWords)
+        let (limited, exceeded) = text.applyingWordLimit(maxWords: Self.maxWords)
         if exceeded {
             text = limited
-            errorMessage = WordLimit.message(maxWords: Self.maxWords)
-        } else if errorMessage == WordLimit.message(maxWords: Self.maxWords) {
+            errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
+        } else if errorMessage == String.wordLimitExceededMessage(maxWords: Self.maxWords) {
             errorMessage = nil
         }
         if hasResults {

+ 6 - 6
gramora/ViewModels/SpellCheckerViewModel.swift

@@ -42,7 +42,7 @@ final class SpellCheckerViewModel: ObservableObject {
 
     func pasteText() {
         guard let clipboard = NSPasteboard.general.string(forType: .string) else { return }
-        text = WordLimit.applyImported(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+        text = String.importedApplyingWordLimit(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
         resetResults()
     }
 
@@ -50,7 +50,7 @@ final class SpellCheckerViewModel: ObservableObject {
         Task {
             do {
                 guard let extracted = try await textExtractionService.pickAndExtractText() else { return }
-                text = WordLimit.applyImported(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+                text = String.importedApplyingWordLimit(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
                 resetResults()
             } catch {
                 errorMessage = error.localizedDescription
@@ -59,15 +59,15 @@ final class SpellCheckerViewModel: ObservableObject {
     }
 
     func notifyWordLimitReached() {
-        errorMessage = WordLimit.message(maxWords: Self.maxWords)
+        errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
     }
 
     func handleTextChange() {
-        let (limited, exceeded) = WordLimit.apply(text, maxWords: Self.maxWords)
+        let (limited, exceeded) = text.applyingWordLimit(maxWords: Self.maxWords)
         if exceeded {
             text = limited
-            errorMessage = WordLimit.message(maxWords: Self.maxWords)
-        } else if errorMessage == WordLimit.message(maxWords: Self.maxWords) {
+            errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
+        } else if errorMessage == String.wordLimitExceededMessage(maxWords: Self.maxWords) {
             errorMessage = nil
         }
         if hasResults {

+ 6 - 6
gramora/ViewModels/SummarizerViewModel.swift

@@ -36,7 +36,7 @@ final class SummarizerViewModel: ObservableObject {
 
     func pasteText() {
         guard let clipboard = NSPasteboard.general.string(forType: .string) else { return }
-        text = WordLimit.applyImported(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+        text = String.importedApplyingWordLimit(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
         summary = ""
     }
 
@@ -44,7 +44,7 @@ final class SummarizerViewModel: ObservableObject {
         Task {
             do {
                 guard let extracted = try await textExtractionService.pickAndExtractText() else { return }
-                text = WordLimit.applyImported(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+                text = String.importedApplyingWordLimit(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
                 summary = ""
             } catch {
                 errorMessage = error.localizedDescription
@@ -53,15 +53,15 @@ final class SummarizerViewModel: ObservableObject {
     }
 
     func notifyWordLimitReached() {
-        errorMessage = WordLimit.message(maxWords: Self.maxWords)
+        errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
     }
 
     func handleTextChange() {
-        let (limited, exceeded) = WordLimit.apply(text, maxWords: Self.maxWords)
+        let (limited, exceeded) = text.applyingWordLimit(maxWords: Self.maxWords)
         if exceeded {
             text = limited
-            errorMessage = WordLimit.message(maxWords: Self.maxWords)
-        } else if errorMessage == WordLimit.message(maxWords: Self.maxWords) {
+            errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
+        } else if errorMessage == String.wordLimitExceededMessage(maxWords: Self.maxWords) {
             errorMessage = nil
         }
         if !summary.isEmpty {

+ 6 - 6
gramora/ViewModels/WordsCountViewModel.swift

@@ -48,14 +48,14 @@ final class WordsCountViewModel: ObservableObject {
 
     func pasteText() {
         guard let clipboard = NSPasteboard.general.string(forType: .string) else { return }
-        text = WordLimit.applyImported(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+        text = String.importedApplyingWordLimit(clipboard, maxWords: Self.maxWords, setError: { errorMessage = $0 })
     }
 
     func uploadFile() {
         Task {
             do {
                 guard let extracted = try await textExtractionService.pickAndExtractText() else { return }
-                text = WordLimit.applyImported(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
+                text = String.importedApplyingWordLimit(extracted, maxWords: Self.maxWords, setError: { errorMessage = $0 })
             } catch {
                 errorMessage = error.localizedDescription
             }
@@ -63,15 +63,15 @@ final class WordsCountViewModel: ObservableObject {
     }
 
     func notifyWordLimitReached() {
-        errorMessage = WordLimit.message(maxWords: Self.maxWords)
+        errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
     }
 
     func handleTextChange() {
-        let (limited, exceeded) = WordLimit.apply(text, maxWords: Self.maxWords)
+        let (limited, exceeded) = text.applyingWordLimit(maxWords: Self.maxWords)
         if exceeded {
             text = limited
-            errorMessage = WordLimit.message(maxWords: Self.maxWords)
-        } else if errorMessage == WordLimit.message(maxWords: Self.maxWords) {
+            errorMessage = String.wordLimitExceededMessage(maxWords: Self.maxWords)
+        } else if errorMessage == String.wordLimitExceededMessage(maxWords: Self.maxWords) {
             errorMessage = nil
         }
     }