apple-apis 0.1.0

System bindings for Apple APIs
import AppleApisUtil
import AppleApisReprC

class StringRef: RawPtrExt {
	var inner: String

	init() {
		self.inner = ""
	}
}

@_cdecl("apple_apis_swift_string_drop")
func string_drop(ptr: Ptr) {
	StringRef.unsafeDropPtr(ptr)
}

@_cdecl("apple_apis_swift_string_new")
func string_new() -> Ptr {
	StringRef().unsafeIntoPtr()
}

@_cdecl("apple_apis_swift_string_extend")
func string_extend(
	ptr: Ptr,
	iter: Ptr,
	len: UInt,
	advance_iter: @convention(c) (Ptr) -> ReprCBoolU32
) {
	let string = StringRef.unsafeFromPtr(ptr)

	// guessing by "number of ASCII characters" they mean bytes
	// or close enough to it... also alloc max in rust is isize::MAX
	// anyways so Int(len) won't overflow or anything
	string.inner.reserveCapacity(Int(len))

	while true {
		let next = advance_iter(iter)
		if !next.val_bool { break }

		// unwrap is trusting that rust behaves
		let scalar = Unicode.Scalar(next.val_u32)!;
		let char = Character(scalar)
		// why so many intermediate steps
		string.inner.append(char)
	}
}

@_cdecl("apple_apis_swift_string_iter_chars")
func string_iter_chars(
	ptr: Ptr,
	opaque_this: Ptr,
	next_char: @convention(c) (Ptr, UInt32) -> ()
) {
	let string = StringRef.unsafeFromPtr(ptr);

	for char in string.inner {
		for scalar in char.unicodeScalars {
			next_char(opaque_this, scalar.value)
		}
	}
}