|
2 | 2 |
|
3 | 3 | #include "time_conversion.h"
|
4 | 4 |
|
5 |
| -VALUE public_is_iso8601_time_string(VALUE klass, VALUE value) { |
6 |
| - return is_iso8601_time_string(StringValuePtr(value)) ? Qtrue : Qfalse; |
| 5 | +static ID push_value_id; |
| 6 | + |
| 7 | +static VALUE datetime_writer_write(VALUE self, VALUE value, VALUE writer, |
| 8 | + VALUE key) { |
| 9 | + if (RB_TYPE_P(value, T_STRING)) { |
| 10 | + const char* val = StringValuePtr(value); |
| 11 | + |
| 12 | + // 'Z' in ISO8601 says it's UTC |
| 13 | + if (val[strlen(val) - 1] == 'Z' && is_iso8601_time_string(val) == Qtrue) { |
| 14 | + rb_funcall(writer, push_value_id, 2, value, key); |
| 15 | + return Qtrue; |
| 16 | + } |
| 17 | + |
| 18 | + volatile VALUE iso8601_string = iso_ar_iso_datetime_string(val); |
| 19 | + if (iso8601_string != Qnil) { |
| 20 | + rb_funcall(writer, push_value_id, 2, iso8601_string, key); |
| 21 | + return Qtrue; |
| 22 | + } |
| 23 | + } |
| 24 | + |
| 25 | + return Qfalse; |
7 | 26 | }
|
8 | 27 |
|
9 |
| -VALUE public_iso_ar_iso_datetime_string(VALUE klass, VALUE value) { |
10 |
| - return iso_ar_iso_datetime_string(StringValuePtr(value)); |
| 28 | +// Helper function to safely get a constant if it exists |
| 29 | +static VALUE safe_const_get(VALUE parent, const char* name) { |
| 30 | + if (rb_const_defined(parent, rb_intern(name))) { |
| 31 | + return rb_const_get(parent, rb_intern(name)); |
| 32 | + } |
| 33 | + return Qnil; |
11 | 34 | }
|
12 | 35 |
|
13 | 36 | void Init_panko_serializer() {
|
14 |
| - VALUE mPanko = rb_define_module("Panko"); |
| 37 | + push_value_id = rb_intern("push_value"); |
15 | 38 |
|
16 |
| - rb_define_singleton_method(mPanko, "is_iso8601_time_string", |
17 |
| - public_is_iso8601_time_string, 1); |
18 |
| - rb_define_singleton_method(mPanko, "iso_ar_iso_datetime_string", |
19 |
| - public_iso_ar_iso_datetime_string, 1); |
| 39 | + VALUE mPanko = rb_define_module("Panko"); |
20 | 40 |
|
21 | 41 | panko_init_time(mPanko);
|
| 42 | + |
| 43 | + VALUE impl = safe_const_get(mPanko, "Impl"); |
| 44 | + if (NIL_P(impl)) { |
| 45 | + printf("Not patching\n"); |
| 46 | + return; |
| 47 | + } |
| 48 | + |
| 49 | + VALUE attributes_writer = safe_const_get(impl, "AttributesWriter"); |
| 50 | + if (NIL_P(attributes_writer)) { |
| 51 | + printf("Not patching\n"); |
| 52 | + return; |
| 53 | + } |
| 54 | + |
| 55 | + VALUE active_record = safe_const_get(attributes_writer, "ActiveRecord"); |
| 56 | + if (NIL_P(active_record)) { |
| 57 | + printf("Not patching\n"); |
| 58 | + return; |
| 59 | + } |
| 60 | + |
| 61 | + VALUE values_writer = safe_const_get(active_record, "ValuesWriter"); |
| 62 | + if (NIL_P(values_writer)) { |
| 63 | + printf("Not patching\n"); |
| 64 | + return; |
| 65 | + } |
| 66 | + |
| 67 | + VALUE cDateTimeWriter = safe_const_get(values_writer, "DateTimeWriter"); |
| 68 | + if (NIL_P(cDateTimeWriter)) { |
| 69 | + printf("Not patching\n"); |
| 70 | + } else { |
| 71 | + rb_define_method(cDateTimeWriter, "write", datetime_writer_write, 3); |
| 72 | + } |
22 | 73 | }
|
0 commit comments