Class: CoachZed::ScheduleParser
- Inherits:
-
Object
- Object
- CoachZed::ScheduleParser
- Defined in:
- lib/coach_zed/schedule_parser.rb
Defined Under Namespace
Classes: Error
Class Method Summary collapse
- .extract_json(raw_schedule) ⇒ Object
- .parse(raw_schedule) ⇒ Object
- .validate!(schedule) ⇒ Object
- .validate_day!(day, expected_day_number) ⇒ Object
Class Method Details
.extract_json(raw_schedule) ⇒ Object
18 19 20 21 22 23 24 |
# File 'lib/coach_zed/schedule_parser.rb', line 18 def self.extract_json(raw_schedule) text = raw_schedule.to_s.strip return text unless text.start_with?("```") fenced = text.match(/```(?:json)?\s*(.*?)\s*```/m) fenced ? fenced[1].to_s.strip : text end |
.parse(raw_schedule) ⇒ Object
9 10 11 12 13 14 15 16 |
# File 'lib/coach_zed/schedule_parser.rb', line 9 def self.parse(raw_schedule) json = extract_json(raw_schedule) schedule = JSON.parse(json) validate!(schedule) schedule rescue JSON::ParserError => e raise Error, "invalid schedule JSON: #{e.}" end |
.validate!(schedule) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/coach_zed/schedule_parser.rb', line 26 def self.validate!(schedule) raise Error, "schedule must be a JSON object" unless schedule.is_a?(Hash) days = schedule.fetch("days") raise Error, "schedule must contain days" unless days.is_a?(Array) && !days.empty? expected_length = schedule["program_length_days"] || days.length raise Error, "program_length_days must match days length" unless expected_length.to_i == days.length days.each_with_index do |day, index| validate_day!(day, index + 1) end rescue KeyError => e raise Error, "missing required schedule field: #{e.key}" end |
.validate_day!(day, expected_day_number) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/coach_zed/schedule_parser.rb', line 42 def self.validate_day!(day, expected_day_number) raise Error, "each day must be an object" unless day.is_a?(Hash) raise Error, "day_number must be sequential" unless day.fetch("day_number").to_i == expected_day_number raise Error, "day_type must be workout or rest" unless %w[workout rest].include?(day.fetch("day_type")) raise Error, "notes must be present" unless day.key?("notes") if day["day_type"] == "workout" workout = day.fetch("workout") raise Error, "workout must be present for workout days" unless workout.is_a?(Hash) %w[title catalog_path domain session_duration].each do |field| raise Error, "workout must include #{field}" unless workout[field].is_a?(String) && !workout[field].empty? end end rescue KeyError => e raise Error, "missing required day field: #{e.key}" end |