PostGenerationService.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import Foundation
  2. protocol PostGenerationServiceProtocol: Sendable {
  3. func generatePost(from draft: PostDraft) async throws -> GeneratedPost
  4. }
  5. enum PostGenerationError: LocalizedError {
  6. case emptyTopic
  7. case emptySubreddit
  8. var errorDescription: String? {
  9. switch self {
  10. case .emptyTopic: "Enter a topic or keywords for AI generation."
  11. case .emptySubreddit: "Enter a subreddit to tailor the post."
  12. }
  13. }
  14. }
  15. struct MockPostGenerationService: PostGenerationServiceProtocol {
  16. func generatePost(from draft: PostDraft) async throws -> GeneratedPost {
  17. guard !draft.subreddit.trimmingCharacters(in: .whitespaces).isEmpty else {
  18. throw PostGenerationError.emptySubreddit
  19. }
  20. guard !draft.topic.trimmingCharacters(in: .whitespaces).isEmpty else {
  21. throw PostGenerationError.emptyTopic
  22. }
  23. try await Task.sleep(for: .milliseconds(900))
  24. let subreddit = draft.subreddit.replacingOccurrences(of: "r/", with: "")
  25. let topic = draft.topic.trimmingCharacters(in: .whitespaces)
  26. let tone = draft.tone.title.lowercased()
  27. let title = makeTitle(topic: topic, subreddit: subreddit, tone: draft.tone)
  28. let body = makeBody(
  29. topic: topic,
  30. subreddit: subreddit,
  31. tone: tone,
  32. postType: draft.postType
  33. )
  34. let flair = suggestFlair(for: draft.postType, subreddit: subreddit)
  35. return GeneratedPost(title: title, body: body, suggestedFlair: flair)
  36. }
  37. private func makeTitle(topic: String, subreddit: String, tone: PostTone) -> String {
  38. switch tone {
  39. case .humorous:
  40. "I tried \(topic) so you don't have to — r/\(subreddit) was not wrong"
  41. case .professional:
  42. "Analysis: \(topic) — findings from r/\(subreddit)"
  43. case .informative:
  44. "Everything you need to know about \(topic) [Guide]"
  45. case .controversial:
  46. "Unpopular opinion: \(topic) is overrated. Change my mind."
  47. case .storytelling:
  48. "How \(topic) completely changed my perspective"
  49. case .casual:
  50. "Anyone else obsessed with \(topic) lately?"
  51. }
  52. }
  53. private func makeBody(
  54. topic: String,
  55. subreddit: String,
  56. tone: String,
  57. postType: RedditPostType
  58. ) -> String {
  59. switch postType {
  60. case .text:
  61. """
  62. Hey r/\(subreddit),
  63. I've been diving deep into **\(topic)** and wanted to share what I've learned.
  64. **Key points:**
  65. - Started exploring this after seeing it trending here
  66. - The community's take has been incredibly helpful
  67. - Still have a few open questions (see below)
  68. **My experience:**
  69. This started as a casual experiment but turned into something I genuinely care about. Would love to hear how others in this subreddit approach \(topic).
  70. **Questions for the community:**
  71. 1. What's your go-to resource for \(topic)?
  72. 2. Any common mistakes beginners should avoid?
  73. 3. Who else here is working on something similar?
  74. Written in a \(tone) tone — happy to refine based on feedback!
  75. """
  76. case .image:
  77. "Caption: A visual breakdown of \(topic) — details in the comments. Let me know what you think!"
  78. case .link:
  79. "Found this great resource on \(topic). Thought r/\(subreddit) would find it useful. Summary in comments."
  80. case .video:
  81. "Just watched this breakdown of \(topic) and had to share. The section at 3:42 really nails it."
  82. case .poll:
  83. "Curious where r/\(subreddit) stands on \(topic). Vote below!"
  84. }
  85. }
  86. private func suggestFlair(for postType: RedditPostType, subreddit: String) -> String {
  87. switch postType {
  88. case .text: "Discussion"
  89. case .image: "Media"
  90. case .link: "News"
  91. case .video: "Video"
  92. case .poll: "Poll"
  93. }
  94. }
  95. }