Class: Code::Object::Ics

Inherits:
Code::Object show all
Defined in:
lib/code/object/ics.rb

Constant Summary collapse

EVENT_ATTRIBUTES =
i[
  uid
  summary
  description
  location
  url
  status
  organizer
  categories
  attendees
  geo
].freeze

Constants inherited from Code::Object

NUMBER_CLASSES

Instance Attribute Summary

Attributes included from Concerns::Shared

#methods, #raw

Class Method Summary collapse

Methods inherited from Code::Object

code_new, #code_new, #initialize, maybe, #name, repeat, |

Methods included from Concerns::Shared

#<=>, #==, #as_json, #blank?, #call, #code_and, #code_as_json, #code_blank?, #code_compare, #code_deep_duplicate, #code_different, #code_duplicate, #code_equal, #code_exclamation_mark, #code_exclusive_range, #code_falsy?, #code_fetch, code_fetch, code_get, #code_get, #code_greater, #code_greater_or_equal, #code_inclusive_range, #code_inspect, #code_less, #code_less_or_equal, #code_methods, #code_name, #code_nothing?, #code_or, #code_presence, #code_presence_in, #code_present?, #code_self, code_set, #code_set, #code_something?, #code_strict_different, #code_strict_equal, #code_to_boolean, #code_to_class, #code_to_date, #code_to_decimal, #code_to_dictionary, #code_to_duration, #code_to_integer, #code_to_json, #code_to_list, #code_to_nothing, #code_to_parameter, #code_to_range, #code_to_string, #code_to_time, #code_truthy?, #eql?, #falsy?, #hash, #inspect, #multi_fetch, #nothing?, #present?, #sig, #something?, #succ, #to_code, #to_i, #to_json, #to_s, #truthy?

Constructor Details

This class inherits a constructor from Code::Object

Class Method Details

.call(**args) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/code/object/ics.rb', line 19

def self.call(**args)
  code_operator = args.fetch(:operator, nil).to_code
  code_arguments = args.fetch(:arguments, []).to_code
  code_value = code_arguments.code_first

  case code_operator.to_s
  when "parse"
    sig(args) { String }
    code_parse(code_value)
  else
    super
  end
end

.code_parse(value) ⇒ Object



33
34
35
36
37
38
39
40
41
42
# File 'lib/code/object/ics.rb', line 33

def self.code_parse(value)
  source = value.to_code.raw
  calendars = ::Icalendar::Calendar.parse(source)
  calendars
    .flat_map(&:events)
    .map { |event| serialize_event(event) }
    .to_code
rescue StandardError
  [].to_code
end

.serialize_date_like(value) ⇒ Object



83
84
85
86
87
88
89
90
# File 'lib/code/object/ics.rb', line 83

def self.serialize_date_like(value)
  case value
  when ::Time, ::Date, ::ActiveSupport::TimeWithZone
    value
  when ::DateTime
    value.to_time
  end
end

.serialize_event(event) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/code/object/ics.rb', line 44

def self.serialize_event(event)
  EVENT_ATTRIBUTES.each_with_object({}) do |attribute, result|
    next unless event.respond_to?(attribute)

    serialized = serialize_value(event.public_send(attribute))
    serialized = serialized.flatten(1) if attribute == :categories && serialized.is_a?(::Array)
    result[attribute] = serialized unless serialized.nil?
  end.merge(
    timestamp: serialize_value(event.dtstamp),
    starts_at: serialize_value(event.dtstart),
    ends_at: serialize_value(event.dtend),
    all_day: !!serialize_date_like(event.dtstart).is_a?(::Date)
  ).compact
end

.serialize_value(value) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/code/object/ics.rb', line 59

def self.serialize_value(value)
  case value
  when nil
    nil
  when ::String, ::Symbol, ::Integer, ::Float, ::BigDecimal, true, false
    value
  when ::Array
    value.map { |item| serialize_value(item) }
  when ::Hash
    value.transform_values { |item| serialize_value(item) }
  else
    serialized_date = serialize_date_like(value)
    return serialized_date unless serialized_date.nil?

    if value.respond_to?(:value)
      serialize_value(value.value)
    elsif value.respond_to?(:to_ical)
      value.to_ical
    else
      value.to_s
    end
  end
end