birthdays: match to_s and to_line on the component shape
Birthday.new already dispatches on the same tuple, so to_s's clauses
now run in its order — the order its comment already claimed.

Assisted-by: Claude Opus 5 via Claude Code
change tswokzttxmxnwwurkwznpqtzuwykzkpl
commit 53c04a1d433467250a372e6fb3b125dba886e3df
author Alpha Chen <alpha@kejadlen.dev>
date
parent omxtqpon
diff --git a/lib/pro_tacts/birthday.rb b/lib/pro_tacts/birthday.rb
index 6c99b41..beb8173 100644
--- a/lib/pro_tacts/birthday.rb
+++ b/lib/pro_tacts/birthday.rb
@@ -113,10 +113,13 @@ module ProTacts
     # UNRENDERED_VALUES is exactly those four shapes' spellings, so
     # widening this means narrowing that.
     def to_line
-      if year && month && day
-        format("BDAY:%04d-%02d-%02d", year, month, day)
-      elsif month && day
-        format("BDAY;X-APPLE-OMIT-YEAR=1604:1604-%02d-%02d", month, day)
+      case [year, month, day]
+      in [Integer => y, Integer => m, Integer => d]
+        format("BDAY:%04d-%02d-%02d", y, m, d)
+      in [nil, Integer => m, Integer => d]
+        format("BDAY;X-APPLE-OMIT-YEAR=1604:1604-%02d-%02d", m, d)
+      else
+        nil
       end
     end
 
@@ -125,20 +128,22 @@ module ProTacts
     # birthday agrees. Carries no calendar: the components were
     # range-checked when built, and Date.new would only add a way to
     # fail, on a value like February 30 that is impossible but
-    # well-shaped and renders as the day it names.
+    # well-shaped and renders as the day it names. No else: the six are
+    # every shape a Birthday holds, so a seventh is better raising here
+    # than rendering as whichever clause it fell through to.
     def to_s
-      y, m, d = year, month, day
-      if y && m && d
+      case [year, month, day]
+      in [Integer => y, Integer => m, Integer => d]
         "#{Date::MONTHNAMES[m]} #{d}, #{y}"
-      elsif m && d
-        "#{Date::MONTHNAMES[m]} #{d}"
-      elsif y && m
+      in [Integer => y, Integer => m, nil]
         "#{Date::MONTHNAMES[m]} #{y}"
-      elsif y
+      in [Integer => y, nil, nil]
         y.to_s
-      elsif m
-        "#{Date::MONTHNAMES[m]}"
-      else
+      in [nil, Integer => m, Integer => d]
+        "#{Date::MONTHNAMES[m]} #{d}"
+      in [nil, Integer => m, nil]
+        Date::MONTHNAMES[m].to_s
+      in [nil, nil, Integer => d]
         d.to_s
       end
     end