glib

MoonBit bindings for GLib non-GObject types (GError, GMainLoop, GVariant, etc.)

glib
ffi
native
gtk
moon add tonyfettes/glib@0.2.0
Download zip
Version
0.2.0
License
Apache-2.0
Last updated
23 days ago
Downloads
255
README

#GLib Bindings for MoonBit

This package provides MoonBit bindings for the GLib C library, offering error handling and event loop functionality. All types are GC-managed — no manual free() or unref() needed.

#Features

  • Error Handling: Error_ with domain, code, and message
  • Event Loop: MainLoop and MainContext

#Requirements

The GLib library (libglib-2.0.so) must be installed on your system.

#Usage

#Error Handling with Error_

///|
test {
let error = @glib.Error_::new(1U, 42, "Operation failed")

assert_eq(error.domain(), 1U)
assert_eq(error.code(), 42)
assert_true(error.message().contains("Operation failed"))

assert_true(error.matches(1U, 42))
assert_false(error.matches(1U, 99))

let copy = error.copy()
assert_eq(copy.code(), error.code())
// No need to free — GC handles cleanup
}

#Main Event Loop

///|
test {
let ctx = @glib.MainContext::new()
let main_loop = @glib.MainLoop::new(ctx, false)

assert_false(main_loop.is_running())
assert_false(ctx.pending())

let dispatched = ctx.iteration(false)
assert_false(dispatched)
// No need to unref — GC handles cleanup
}

#Using Default Context

///|
test {
let main_loop = @glib.MainLoop::new_default(false)
let ctx = main_loop.get_context()
let _ = ctx
}

#API Reference

#Error_ Methods

MethodDescription
Error_::new(domain, code, message)Create new error
error.copy()Deep copy error
error.matches(domain, code)Check if error matches
error.message()Get error message
error.code()Get error code
error.domain()Get error domain

#MainContext Methods

MethodDescription
MainContext::new()Create new context
MainContext::default()Get global default context
ctx.iteration(may_block)Run one iteration
ctx.pending()Check for pending events
ctx.wakeup()Wake up blocked context

#MainLoop Methods

MethodDescription
MainLoop::new(ctx, is_running)Create with context
MainLoop::new_default(is_running)Create with default context
loop.run()Run until quit
loop.quit()Signal loop to quit
loop.is_running()Check if running
loop.get_context()Get loop's context

#
IUri

pub(open) trait IUri {
fn as_uri(Self) -> Uri
fn get_auth_params(Self) -> String? = _
fn get_flags(Self) -> UriFlags = _
fn get_fragment(Self) -> String? = _
fn get_host(Self) -> String? = _
fn get_password(Self) -> String? = _
fn get_path(Self) -> String = _
fn get_port(Self) -> Int = _
fn get_query(Self) -> String? = _
fn get_scheme(Self) -> String = _
fn get_user(Self) -> String? = _
fn get_userinfo(Self) -> String? = _
fn parse_relative(Self, String, UriFlags) -> Uri raise Error_ = _
fn to_string(Self) -> String = _
fn to_string_partial(Self, UriHideFlags) -> String = _
}

#
IVariant

pub(open) trait IVariant {
fn as_variant(Self) -> Variant
}

#
Error_

pub suberror Error_

Error_ - GLib's error structure. Automatically freed when garbage collected.

#
Error_::code

fn Error_::code(self : Error_) -> Int

Get the error code.

#
Error_::copy

fn Error_::copy(self : Error_) -> Error_

Deep copy an Error_.

#
Error_::domain

fn Error_::domain(self : Error_) -> UInt

Get the error domain (GQuark).

#
Error_::matches

fn Error_::matches(self : Error_, domain : UInt, code : Int) -> Bool

Check if error matches the specified domain and code.

Example

test {
let error = @glib.Error_::new(5U, 100, "Network error")
assert_true(error.matches(5U, 100))
assert_false(error.matches(5U, 101))
assert_false(error.matches(6U, 100))
}

#
Error_::message

fn Error_::message(self : Error_) -> String

Get the error message.

#
Error_::new

fn Error_::new(domain : UInt, code : Int, message : String) -> Error_

Create a new Error_.

Example

test {
let error = @glib.Error_::new(1U, 42, "Something went wrong")
assert_eq(error.code(), 42)
assert_eq(error.domain(), 1U)
assert_true(error.message().contains("Something went wrong"))
}

#
HashTable

#external
pub type HashTable

#
HashTable::insert_str_str

fn HashTable::insert_str_str(self : HashTable, key : Bytes, value : Bytes) -> Unit

Insert a string key/value (both copied into the table).

#
HashTable::iter

fn HashTable::iter(self : HashTable) -> HashTableIter

Open an iterator positioned before the first entry.

#
HashTable::new_str

fn HashTable::new_str() -> HashTable

Build an empty owned GHashTable<utf8,utf8> (string hash/equal, frees both key and value). For the parameter direction.

#
HashTable::size

fn HashTable::size(self : HashTable) -> Int

Number of entries.

#
HashTable::unref

fn HashTable::unref(self : HashTable) -> Unit

Drop a logical reference. Call this on tables you own (a transfer-full return, or one you built with new_str), never on a borrowed table.

#
HashTableIter

pub type HashTableIter

GC-managed iterator over a HashTable's entries. Reclaimed automatically; the underlying table must outlive it (it always does within a wrapper).

#
HashTableIter::key_bytes

fn HashTableIter::key_bytes(self : HashTableIter) -> Bytes

Current entry's key as the raw bytes of a C string (utf8/filename keys).

#
HashTableIter::key_int

fn HashTableIter::key_int(self : HashTableIter) -> Int

Current entry's key as an int (primitive / enum / bool keys).

#
HashTableIter::next

fn HashTableIter::next(self : HashTableIter) -> Bool

Advance to the next entry; returns false once the entries are exhausted.

#
HashTableIter::val_bytes

fn HashTableIter::val_bytes(self : HashTableIter) -> Bytes

Current entry's value as the raw bytes of a C string.

#
HashTableIter::val_int

fn HashTableIter::val_int(self : HashTableIter) -> Int

Current entry's value as an int.

#
IOCondition

pub struct IOCondition {
// private fields
}

#
IOCondition::IOCondition

fn IOCondition::IOCondition(flags : Array[IOConditionFlag]) -> IOCondition

#
IOCondition::from_int

fn IOCondition::from_int(value : Int) -> IOCondition

#
IOCondition::to_int

fn IOCondition::to_int(self : IOCondition) -> Int

#
IOConditionFlag

pub(all) enum IOConditionFlag {
In
Out
Pri
Err
Hup
Nval
}

#
MainContext

pub type MainContext

MainContext - event source context. Automatically unreffed when garbage collected.

#
MainContext::default

fn MainContext::default() -> MainContext

Get the global default MainContext.

#
MainContext::iteration

fn MainContext::iteration(self : MainContext, may_block : Bool) -> Bool

Run a single iteration. Returns true if events were dispatched.

#
MainContext::new

Create a new MainContext.

Example

test {
let ctx = @glib.MainContext::new()
assert_false(ctx.pending())
}

#
MainContext::pending

fn MainContext::pending(self : MainContext) -> Bool

Check if there are pending events.

#
MainContext::wakeup

fn MainContext::wakeup(self : MainContext) -> Unit

Wake up the context if blocked in a poll.

#
MainLoop

pub type MainLoop

MainLoop - main event loop. Automatically unreffed when garbage collected.

#
MainLoop::get_context

fn MainLoop::get_context(self : MainLoop) -> MainContext

Get the context of the main loop.

#
MainLoop::is_running

fn MainLoop::is_running(self : MainLoop) -> Bool

Check if the main loop is running.

#
MainLoop::new

fn MainLoop::new(context : MainContext, is_running : Bool) -> MainLoop

Create a new MainLoop with the given context.

Example

test {
let ctx = @glib.MainContext::new()
let main_loop = @glib.MainLoop::new(ctx, false)
assert_false(main_loop.is_running())
}

#
MainLoop::new_default

fn MainLoop::new_default(is_running : Bool) -> MainLoop

Create a new MainLoop with the default context.

Example

test {
let main_loop = @glib.MainLoop::new_default(false)
assert_false(main_loop.is_running())
}

#
MainLoop::quit

fn MainLoop::quit(self : MainLoop) -> Unit

Signal the main loop to quit.

#
MainLoop::run

fn MainLoop::run(self : MainLoop) -> Unit

Run the main loop until quit is called. Blocks the current thread.

#
Mutex

pub type Mutex

An owned GLib mutex.

The mutex is initialized on construction and cleared when its MoonBit wrapper is collected. It is non-recursive, matching GMutex.

#
Mutex::lock

fn Mutex::lock(self : Mutex) -> Unit

Blocks until this mutex is acquired.

#
Mutex::new

fn Mutex::new() -> Mutex

Creates an initialized mutex.

#
Mutex::try_lock

fn Mutex::try_lock(self : Mutex) -> Bool

Attempts to acquire this mutex without blocking.

#
Mutex::unlock

fn Mutex::unlock(self : Mutex) -> Unit

Releases a mutex held by the current thread.

#
Nullable

type Nullable[T]

#
Nullable::null

fn[T] Nullable::null() -> Nullable[T]

#
Nullable::some

fn[T] Nullable::some(value : T) -> Nullable[T]

#
Nullable::to_option

fn[T] Nullable::to_option(self : Nullable[T]) -> T?

#
SeekType

pub(all) enum SeekType {
Cur
Set
End
}

#
Uri

pub type Uri
impl IUri for Uri

#
Uri::build

fn Uri::build(flags : UriFlags, scheme : String, userinfo : String?, host : String?, port : Int, path : String, query : String?, fragment : String?) -> Uri

#
Uri::build_with_user

fn Uri::build_with_user(flags : UriFlags, scheme : String, user : String?, password : String?, auth_params : String?, host : String?, port : Int, path : String, query : String?, fragment : String?) -> Uri

#
Uri::error_quark

fn Uri::error_quark() -> UInt

#
Uri::escape_string

fn Uri::escape_string(unescaped : String, reserved_chars_allowed : String?, allow_utf8 : Bool) -> String

#
Uri::get_auth_params

fn Uri::get_auth_params(self : Uri) -> String?

#
Uri::get_flags

fn Uri::get_flags(self : Uri) -> UriFlags

#
Uri::get_fragment

fn Uri::get_fragment(self : Uri) -> String?

#
Uri::get_host

fn Uri::get_host(self : Uri) -> String?

#
Uri::get_password

fn Uri::get_password(self : Uri) -> String?

#
Uri::get_path

fn Uri::get_path(self : Uri) -> String

#
Uri::get_port

fn Uri::get_port(self : Uri) -> Int

#
Uri::get_query

fn Uri::get_query(self : Uri) -> String?

#
Uri::get_scheme

fn Uri::get_scheme(self : Uri) -> String

#
Uri::get_user

fn Uri::get_user(self : Uri) -> String?

#
Uri::get_userinfo

fn Uri::get_userinfo(self : Uri) -> String?

#
Uri::is_valid

fn Uri::is_valid(uri_string : String, flags : UriFlags) -> Bool raise Error_

#
Uri::join

fn Uri::join(flags : UriFlags, scheme : String?, userinfo : String?, host : String?, port : Int, path : String, query : String?, fragment : String?) -> String

#
Uri::join_with_user

fn Uri::join_with_user(flags : UriFlags, scheme : String?, user : String?, password : String?, auth_params : String?, host : String?, port : Int, path : String, query : String?, fragment : String?) -> String

#
Uri::parse

fn Uri::parse(uri_string : String, flags : UriFlags) -> Uri raise Error_

#
Uri::parse_params

fn Uri::parse_params(params : String, length : Int64, separators : String, flags : UriParamsFlags) -> Map[String, String] raise Error_

#
Uri::parse_relative

fn Uri::parse_relative(self : Uri, uri_ref : String, flags : UriFlags) -> Uri raise Error_

#
Uri::parse_scheme

fn Uri::parse_scheme(uri : String) -> String?

#
Uri::peek_scheme

fn Uri::peek_scheme(uri : String) -> String?

#
Uri::resolve_relative

fn Uri::resolve_relative(base_uri_string : String?, uri_ref : String, flags : UriFlags) -> String raise Error_

#
Uri::split

fn Uri::split(uri_ref : String, flags : UriFlags) -> (String?, String?, String?, Int, String, String?, String?) raise Error_

#
Uri::split_network

fn Uri::split_network(uri_string : String, flags : UriFlags) -> (String?, String?, Int) raise Error_

#
Uri::split_with_user

fn Uri::split_with_user(uri_ref : String, flags : UriFlags) -> (String?, String?, String?, String?, String?, Int, String, String?, String?) raise Error_

#
Uri::to_string

fn Uri::to_string(self : Uri) -> String

#
Uri::to_string_partial

fn Uri::to_string_partial(self : Uri, flags : UriHideFlags) -> String

#
Uri::unescape_bytes

fn Uri::unescape_bytes(escaped_string : String, length : Int64, illegal_characters : String?) -> Bytes raise Error_

#
Uri::unescape_segment

fn Uri::unescape_segment(escaped_string : String?, escaped_string_end : String?, illegal_characters : String?) -> String?

#
Uri::unescape_string

fn Uri::unescape_string(escaped_string : String, illegal_characters : String?) -> String?

#
UriFlag

pub(all) enum UriFlag {
None
ParseRelaxed
HasPassword
HasAuthParams
Encoded
NonDns
EncodedQuery
EncodedPath
EncodedFragment
SchemeNormalize
}

#
UriFlags

pub struct UriFlags {
// private fields
}

#
UriFlags::UriFlags

fn UriFlags::UriFlags(flags : Array[UriFlag]) -> UriFlags

#
UriFlags::from_int

fn UriFlags::from_int(value : Int) -> UriFlags

#
UriFlags::to_int

fn UriFlags::to_int(self : UriFlags) -> Int

#
UriHideFlag

pub(all) enum UriHideFlag {
None
Userinfo
Password
AuthParams
Query
Fragment
}

#
UriHideFlags

pub struct UriHideFlags {
// private fields
}

#
UriHideFlags::UriHideFlags

fn UriHideFlags::UriHideFlags(flags : Array[UriHideFlag]) -> UriHideFlags

#
UriHideFlags::from_int

fn UriHideFlags::from_int(value : Int) -> UriHideFlags

#
UriHideFlags::to_int

fn UriHideFlags::to_int(self : UriHideFlags) -> Int

#
UriParamsFlag

pub(all) enum UriParamsFlag {
None
CaseInsensitive
WwwForm
ParseRelaxed
}

#
UriParamsFlags

pub struct UriParamsFlags {
// private fields
}

#
UriParamsFlags::UriParamsFlags

fn UriParamsFlags::UriParamsFlags(flags : Array[UriParamsFlag]) -> UriParamsFlags

#
UriParamsFlags::from_int

fn UriParamsFlags::from_int(value : Int) -> UriParamsFlags

#
UriParamsFlags::to_int

fn UriParamsFlags::to_int(self : UriParamsFlags) -> Int

#
Variant

pub type Variant

impl IVariant for Variant

#
Variant::as_bool

fn Variant::as_bool(self : Variant) -> Bool?

Get the boolean value, or None if the variant is not of type "b".

#
Variant::as_double

fn Variant::as_double(self : Variant) -> Double?

Get the double value, or None if not of type "d".

#
Variant::as_int32

fn Variant::as_int32(self : Variant) -> Int?

Get the 32-bit signed integer value, or None if not of type "i".

#
Variant::as_int64

fn Variant::as_int64(self : Variant) -> Int64?

Get the 64-bit signed integer value, or None if not of type "x".

#
Variant::as_string

fn Variant::as_string(self : Variant) -> String?

Get the string value, or None if not of type "s".

#
Variant::as_uint32

fn Variant::as_uint32(self : Variant) -> UInt?

Get the 32-bit unsigned integer value, or None if not of type "u".

#
Variant::as_uint64

fn Variant::as_uint64(self : Variant) -> UInt64?

Get the 64-bit unsigned integer value, or None if not of type "t".

#
Variant::from_bool

fn Variant::from_bool(value : Bool) -> Variant

Create a Variant holding a boolean value.

test {
let v = @glib.Variant::from_bool(true)
@debug.assert_eq(v.type_string(), "b")
@debug.assert_eq(v.as_bool(), Some(true))
}

#
Variant::from_double

fn Variant::from_double(value : Double) -> Variant

Create a Variant holding a double-precision float.

#
Variant::from_int32

fn Variant::from_int32(value : Int) -> Variant

Create a Variant holding a 32-bit signed integer.

test {
let v = @glib.Variant::from_int32(42)
@debug.assert_eq(v.type_string(), "i")
@debug.assert_eq(v.as_int32(), Some(42))
}

#
Variant::from_int64

fn Variant::from_int64(value : Int64) -> Variant

Create a Variant holding a 64-bit signed integer.

#
Variant::from_string

fn Variant::from_string(value : String) -> Variant

Create a Variant holding a string.

test {
let v = @glib.Variant::from_string("hello")
@debug.assert_eq(v.type_string(), "s")
@debug.assert_eq(v.as_string(), Some("hello"))
}

#
Variant::from_uint32

fn Variant::from_uint32(value : UInt) -> Variant

Create a Variant holding a 32-bit unsigned integer.

#
Variant::from_uint64

fn Variant::from_uint64(value : UInt64) -> Variant

Create a Variant holding a 64-bit unsigned integer.

#
Variant::is_of_type

fn Variant::is_of_type(self : Variant, type_string : String) -> Bool

Check if this variant is of the given type.

#
Variant::type_string

fn Variant::type_string(self : Variant) -> String

Get the Variant type string (e.g. "s", "i", "b", "(si)").

#
ALLOCATOR_LIST

let ALLOCATOR_LIST : Int

#
ALLOCATOR_NODE

let ALLOCATOR_NODE : Int

#
ALLOCATOR_SLIST

let ALLOCATOR_SLIST : Int

#
ALLOC_AND_FREE

let ALLOC_AND_FREE : Int

#
ALLOC_ONLY

let ALLOC_ONLY : Int

#
ANALYZER_ANALYZING

let ANALYZER_ANALYZING : Int

#
ASCII_DTOSTR_BUF_SIZE

let ASCII_DTOSTR_BUF_SIZE : Int

#
ATOMIC_REF_COUNT_INIT

let ATOMIC_REF_COUNT_INIT : Int

#
BIG_ENDIAN

let BIG_ENDIAN : Int

#
C_STD_VERSION

let C_STD_VERSION : Int

#
DATALIST_FLAGS_MASK

let DATALIST_FLAGS_MASK : Int

#
DATE_BAD_DAY

let DATE_BAD_DAY : Int

#
DATE_BAD_JULIAN

let DATE_BAD_JULIAN : Int

#
DATE_BAD_YEAR

let DATE_BAD_YEAR : Int

#
DIR_SEPARATOR

let DIR_SEPARATOR : Int

#
HAVE_GINT64

let HAVE_GINT64 : Int

#
HAVE_GNUC_VARARGS

let HAVE_GNUC_VARARGS : Int

#
HAVE_GNUC_VISIBILITY

let HAVE_GNUC_VISIBILITY : Int

#
HAVE_GROWING_STACK

let HAVE_GROWING_STACK : Int

#
HAVE_ISO_VARARGS

let HAVE_ISO_VARARGS : Int

#
HOOK_FLAG_USER_SHIFT

let HOOK_FLAG_USER_SHIFT : Int

#
IEEE754_DOUBLE_BIAS

let IEEE754_DOUBLE_BIAS : Int

#
IEEE754_FLOAT_BIAS

let IEEE754_FLOAT_BIAS : Int

#
LITTLE_ENDIAN

let LITTLE_ENDIAN : Int

#
LOG_FATAL_MASK

let LOG_FATAL_MASK : Int

#
LOG_LEVEL_USER_SHIFT

let LOG_LEVEL_USER_SHIFT : Int

#
MAXINT16

let MAXINT16 : Int

#
MAXINT32

let MAXINT32 : Int

#
MAXINT64

let MAXINT64 : Int64

#
MAXINT8

let MAXINT8 : Int

#
MAXUINT16

let MAXUINT16 : UInt

#
MAXUINT32

let MAXUINT32 : UInt

#
MAXUINT64

let MAXUINT64 : UInt64

#
MAXUINT8

let MAXUINT8 : UInt

#
MININT16

let MININT16 : Int

#
MININT32

let MININT32 : Int

#
MININT64

let MININT64 : Int64

#
MININT8

let MININT8 : Int

#
NSEC_PER_SEC

let NSEC_PER_SEC : UInt64

#
PDP_ENDIAN

let PDP_ENDIAN : Int

#
PRIORITY_DEFAULT

let PRIORITY_DEFAULT : Int

#
PRIORITY_DEFAULT_IDLE

let PRIORITY_DEFAULT_IDLE : Int

#
PRIORITY_HIGH

let PRIORITY_HIGH : Int

#
PRIORITY_HIGH_IDLE

let PRIORITY_HIGH_IDLE : Int

#
PRIORITY_LOW

let PRIORITY_LOW : Int

#
REF_COUNT_INIT

let REF_COUNT_INIT : Int

#
SEARCHPATH_SEPARATOR

let SEARCHPATH_SEPARATOR : Int

#
SIZEOF_LONG

let SIZEOF_LONG : Int

#
SIZEOF_SIZE_T

let SIZEOF_SIZE_T : Int

#
SIZEOF_SSIZE_T

let SIZEOF_SSIZE_T : Int

#
SIZEOF_VOID_P

let SIZEOF_VOID_P : Int

#
SYSDEF_AF_INET

let SYSDEF_AF_INET : Int

#
SYSDEF_AF_INET6

let SYSDEF_AF_INET6 : Int

#
SYSDEF_AF_UNIX

let SYSDEF_AF_UNIX : Int

#
SYSDEF_MSG_DONTROUTE

let SYSDEF_MSG_DONTROUTE : Int

#
SYSDEF_MSG_OOB

let SYSDEF_MSG_OOB : Int

#
SYSDEF_MSG_PEEK

let SYSDEF_MSG_PEEK : Int

#
TIME_SPAN_DAY

let TIME_SPAN_DAY : Int64

#
TIME_SPAN_HOUR

let TIME_SPAN_HOUR : Int64

#
TIME_SPAN_MILLISECOND

let TIME_SPAN_MILLISECOND : Int64

#
TIME_SPAN_MINUTE

let TIME_SPAN_MINUTE : Int64

#
TIME_SPAN_SECOND

let TIME_SPAN_SECOND : Int64

#
UNICHAR_MAX_DECOMPOSITION_LENGTH

let UNICHAR_MAX_DECOMPOSITION_LENGTH : Int

#
USEC_PER_SEC

let USEC_PER_SEC : Int

#
VERSION_MIN_REQUIRED

let VERSION_MIN_REQUIRED : Int

#
WIN32_MSG_HANDLE

let WIN32_MSG_HANDLE : Int

#
idle_add

fn idle_add(callback : () -> Bool) -> UInt

Schedule a callback to run when the main loop is idle. The callback returns true to be called again, false to be removed.

#
source_remove

fn source_remove(tag : UInt) -> Bool

Remove a source from the main loop by its ID (as returned by timeout_add or idle_add). Returns true if the source was found and removed.

#
test_get_hash_table

fn test_get_hash_table() -> Map[String, String]

Copy a C-owned table into a Map (return direction), then release it.

#
test_get_list_empty

fn test_get_list_empty() -> Array[String]

#
test_get_list_str

fn test_get_list_str() -> Array[String]

#
test_get_slist_str

fn test_get_slist_str() -> Array[String]

#
test_roundtrip_hash_table

fn test_roundtrip_hash_table(m : Map[String, String]) -> Int

Build a table from a Map (parameter direction), hand it to C, release it.

#
timeout_add

fn timeout_add(interval : UInt, callback : () -> Bool) -> UInt

Schedule a callback to run repeatedly at the given interval (in milliseconds). The callback returns true to continue, false to stop.

#
utf8_collate

fn utf8_collate(left : String, right : String) -> Int

Compares two UTF-8 strings using the current locale's collation rules.