hugopl/gi-crystal

Add support for GLib::String

hugopl opened this issue · 1 comments

Meanwhile GLib::String must be transparent for Crystal users, i.e. translated to Crystal strings.

Thinking about how to support this... I think that the handmade: configuration for types in binding.yml files must be changed.

Instead of having true/false, it could have strings that to be used for the type instead.

Consider the C function bellow:

/**
 * test_subject_concat_g_strings:
 * @str_full: (transfer full)
 * @str_none: (transfer none)
 * Returns: (transfer full)
 *
 * Used to test GLib String bindings.
 */
GString* test_subject_concat_g_strings(GString* str_full, GString* str_none);

Currently if I set the type String has handmade: true, a binding for it will be generated as bellow, note that it still use the GLib::String as return type, it just relax the parameters type restrictions, or better, delegate this to GLib::String.new, good for GValue bindings, useless for GString since we want to make it fully transparent for Crystal developers.

    def self.concat_g_strings(str_full : _, str_none : _) : GLib::String
      # Generator::HandmadeArgPlan
      str_full = if !str_full.is_a?(GLib::String)
                   GLib::String.new(str_full).to_unsafe
                 else
                   str_full.to_unsafe
                 end
      # Generator::HandmadeArgPlan
      str_none = if !str_none.is_a?(GLib::String)
                   GLib::String.new(str_none).to_unsafe
                 else
                   str_none.to_unsafe
                 end
      _retval = LibTest.test_subject_concat_g_strings(str_full, str_none)
      GLib::String.new(_retval, GICrystal::Transfer::Full)
    end

So... if instead of accept only true/false, the handmade option could accept strings to be used as the type in the generated code:

String:
    as_parameter: String
    as_return: String

So the code rendered for the function above could be:

    def self.concat_g_strings(str_full : String, str_none : String) : String
      # Generator::HandmadeArgPlan
      str_full = GICrystal.convert_glib_string_from_crystal(str_full)
      # Generator::HandmadeArgPlan
      str_none = GICrystal.convert_glib_string_from_crystal(str_none)

      _retval = LibTest.test_subject_concat_g_strings(str_full, str_none)
      GICrystal.convert_glib_string_to_crystal(_retval, :full)
    end

GICrystal.convert_glib_string_from_crystal and GICrystal.convert_glib_string_to_crystal would need to be written by the bindings author.

I'm still thinking about the side effects of this, but at a first look seems that GValue bidings can fit on this schema.

Final thoughts

I would like to see if there are other use cases for this, because GLib::String is used nowhere... so this maybe is too much effort to support a type that nobody uses instead of use my energy on something more interesting and useful for more people.