2

I'm trying to write a Crystal wrapper around libevent, and I wondered how to approach its enums that are named as all lower-case, for instance:

enum ev_http_request_error:

I tried the following:

@[Link("event")]
lib LibEvent
  # <snip>
  enum evhttp_request_error
    EVREQ_HTTP_TIMEOUT,
    EVREQ_HTTP_EOF,
    EVREQ_HTTP_INVALID_HEADER,
    EVREQ_HTTP_BUFFER_ERROR,
    EVREQ_HTTP_DATA_TOO_LONG
  end
end

but this fails because evhttp_request_error doesn't fit the grammar for a Crystal constant. How should I address this?

andrewdotnich
  • 16,195
  • 7
  • 38
  • 57

2 Answers2

3

You can name it whatever you want. But when you use enum inside your lib wrapper, you just declare a new C enum:

@[Link("event")]
lib LibEvent
   enum EvHTTPRequestError
     EVREQ_HTTP_TIMEOUT
     EVREQ_HTTP_EOF
     EVREQ_HTTP_INVALID_HEADER
     EVREQ_HTTP_BUFFER_ERROR
     EVREQ_HTTP_DATA_TOO_LONG
  end
end

This is effectively the same as:

@[Link("event")]
lib LibEvent
   enum EvHTTPRequestError
     EVREQ_HTTP_TIMEOUT = 0
     EVREQ_HTTP_EOF = 1
     EVREQ_HTTP_INVALID_HEADER = 2
     EVREQ_HTTP_BUFFER_ERROR = 3
     EVREQ_HTTP_DATA_TOO_LONG = 4
  end
end

and the values in this enum will not match the values from your original C lib.

You need to set (duplicate) correct values manually in your enum.

Since Crystal only binds to a shared library file, there is no option other than manually (sometimes automatically) duplicating these as constants in Crystal code.

Checkout example in Crystal stdlib

Vitalii Elenhaupt
  • 7,146
  • 3
  • 27
  • 43
1

In short, it doesn't matter. The name doesn't need to be an exact match to the C name (it's a glorified int anyway), so provided the values match their counterparts in C-land, Crystal's name for that type can be whatever you want :)

andrewdotnich
  • 16,195
  • 7
  • 38
  • 57