Module trial.arsd.core

Please note: the api and behavior of this module is not externally stable at this time. See the documentation on specific functions for details.

Shared core functionality including exception helpers, library loader, event loop, and possibly more. Maybe command line processor and uda helper and some basic shared annotation types.

I'll probably move the url, websocket, and ssl stuff in here too as they are often shared. Maybe a small internationalization helper type (a hook for external implementation) and COM helpers too. I might move the process helpers out to their own module - even things in here are not considered stable to library users at this time!

If you use this directly outside the arsd library despite its current instability caveats, you might consider using static import since names in here are likely to clash with Phobos if you use them together. static import will let you easily disambiguate and avoid name conflict errors if I add more here. Some names even clash deliberately to remind me to avoid some antipatterns inside the arsd modules!

## Contributor notes

arsd.core should be focused on things that enable interoperability primarily and secondarily increased code quality between other, otherwise independent arsd modules. As a foundational library, it is not permitted to import anything outside the druntime core namespace, except in templates and examples not normally compiled in. This keeps it independent and avoids transitive dependency spillover to end users while also keeping compile speeds fast. To help keep builds snappy, also avoid significant use of ctfe inside this module.

On my linux computer, dmd -unittest -main core.d takes about a quarter second to run. We do not want this to grow.

@safe compatibility is ok when it isn't too big of a hassle. @nogc is a non-goal. I might accept it on some of the trivial functions but if it means changing the logic in any way to support, you will need a compelling argument to justify it. The arsd libs are supposed to be reliable and easy to use. That said, of course, don't be unnecessarily wasteful - if you can easily provide a reliable and easy to use way to let advanced users do their thing without hurting the other cases, let's discuss it.

If functionality is not needed by multiple existing arsd modules, consider adding a new module instead of adding it to the core.

Unittests should generally be hidden behind a special version guard so they don't interfere with end user tests.

History

Added March 2023 (dub v11.0). Several functions were migrated in here at that time, noted individually. Members without a note were added with the module.

Functions

NameDescription
arsd_core_init(numberOfWorkers) Initializes the arsd core event loop and creates its worker threads. You don't actually have to call this, since the first use of an arsd.core function that requires it will call it implicitly, but calling it yourself gives you a chance to control the configuration more explicitly if you want to.
asTheyComplete(requests) Waits for all the requests to complete, giving each one through the range interface as it completes.
castTo(v) Casts value v to type T.
dumpParamsImpl(func, args) Don't call this directly, use mixin(dumpParams); instead
enumNameForValue(t)
ErrnoEnforce(params, sentinel, file, line) Calls the C API function fn. If it returns an error value, it throws an [ErrnoApiException] (or subclass) after getting errno.
flagsToString(value)
getCurrentWorkingDirectory()
getFiles(directory, dg) Note that the order of items called for your delegate is undefined; if you want it sorted, you'll have to collect and sort yourself. But it *might* be sorted by the OS (on Windows, it almost always is), so consider that when choosing a sorting algorithm.
getThisThreadEventLoop(type) Get the event loop associated with this thread
inSchedulableTask() Gets an object that lets you control a schedulable task (which is a specialization of a fiber) and can be used in an if statement.
intToString(value, buffer, args) An int printing function that doesn't need to import Phobos. Can do some of the things std.conv.to and std.format.format do.
isSliceOf(needle, haystack) Determines whether needle is a slice of haystack.
logSwallowedException(e) Makes note of an exception you catch and otherwise ignore.
mallocedStringz(original) Uses C's malloc to allocate a copy of original with an attached zero terminator. It may return a slice with a null pointer (but non-zero length!) if malloc fails and you are responsible for freeing the returned pointer with core.stdc.stdlib.free(ret.ptr).
mallocSlice(n) A trivial wrapper around C's malloc that creates a D slice. It multiples n by T.sizeof and returns the slice of the pointer from 0 to n.
matchesFilePattern(name, pattern) This is currently a simplified glob where only the * wildcard in the first or last position gets special treatment or a single * in the middle.
populateFromArgs(args) This populates a struct from a list of values (or other expressions, but it only looks at the values) based on types of the members, with one exception: bool members.. maybe.
provideBuffer(buffer, policy) Some functions that return arrays allow you to provide your own buffer. These are indicated in the type system as UserProvidedBuffer!Type, and you get to decide what you want to happen if the buffer is too small via the [OnOutOfSpace] parameter.
readBinaryFile(filename) Reads or writes a file in one call. It might internally yield, but is generally blocking if it returns values. The callback ones depend on the implementation.
readTextFile(filename, fileEncoding) Reads or writes a file in one call. It might internally yield, but is generally blocking if it returns values. The callback ones depend on the implementation.
reinterpretCast(value) Treats the memory of one variable as if it is the type of another variable.
stripInternal(s)
stripRightInternal(s)
toStringInternal(t) Shortcut for converting some types to string without invoking Phobos (but it may as a last resort).
waitForFirstToComplete(requests) It returns the request so you can identify it more easily. request.waitForCompletion() is guaranteed to return the response without any actual wait, since it is already complete when this function returns.
waitForFirstToCompleteByIndex(requests) It returns the request so you can identify it more easily. request.waitForCompletion() is guaranteed to return the response without any actual wait, since it is already complete when this function returns.
writeFile(filename, contents) Reads or writes a file in one call. It might internally yield, but is generally blocking if it returns values. The callback ones depend on the implementation.
writeln(t) A writeln that actually works, at least for some basic types.
writelnStderr(t)

Interfaces

NameDescription
AsyncOperationResponse
ICoreEventLoop
LogListenerController DO NOT USE THIS YET IT IS NOT FUNCTIONAL NOR STABLE

Classes

NameDescription
AbstractFile An AbstractFile represents a file handle on the operating system level. You cannot do much with it.
ArsdException This is a generic exception with attached arguments. It is used when I had to throw something but didn't want to write a new class.
ArsdExceptionBase Base class representing my exceptions. You should almost never work with this directly, but you might catch it as a generic thing. Catch it before generic object.Exception or object.Throwable in any catch chains.
AsyncAcceptRequest Calls AcceptEx on Windows and emulates it on other systems.
AsyncAcceptResponse
AsyncConnectRequest Initiates a connection request and optionally sends initial data as soon as possible.
AsyncConnectResponse
AsyncFile Only one operation can be pending at any time in the current implementation.
AsyncOperationRequest Represents a generic async, waitable request.
AsyncReadRequest
AsyncReadResponse
AsyncReceiveRequest
AsyncReceiveResponse
AsyncSendRequest
AsyncSendResponse
AsyncWriteRequest You can write to a file asynchronously by creating one of these.
AsyncWriteResponse
DatagramListener A socket bound and ready to use receiveFrom
DirectoryWatcher PARTIALLY IMPLEMENTED / NOT STABLE
ExternalProcess UNSTABLE, NOT FULLY IMPLEMENTED. DO NOT USE YET.
FeatureUnavailableException Base class for when you've requested a feature that is not available. It may not be available because it is possible, but not yet implemented, or it might be because it is impossible on your operating system.
File
InvalidArgumentsException
LoggerOf DO NOT USE THIS YET IT IS NOT FUNCTIONAL NOR STABLE
NotSupportedException This means the feature is not supported by your current operating system. You might be able to get it in an update, but you might just have to find an alternate way of doing things.
NotYetImplementedException This means the feature could be done, but I haven't gotten around to implementing it yet. If you email me, I might be able to add it somewhat quickly and get back to you.
ReadableStream A stream can be used by just one task at a time, but one task can consume multiple streams.
SingleInstanceApplication This starts up a local pipe. If it is already claimed, it just communicates with the existing one through the interface.
StreamServer A set of sockets bound and ready to accept connections on worker threads.
SystemApiException
Timer A timer that will trigger your function on a given interval.
TranslationEngine Represents a translatable string.
tstring Represents a translatable string.
WritableStream A class to help write a stream of binary data to some target.

Structs

NameDescription
ArgSentinel This is a dummy type to indicate the end of normal arguments and the beginning of the file/line inferred args. It is meant to ensure you don't accidentally send a string that is interpreted as a filename when it was meant to be a normal argument to the function and trigger the wrong overload.
ArsdCoreApplication To opt in to the full functionality of this module with customization opportunity, create one and only one of these objects that is valid for exactly the lifetime of the application.
AsTheyCompleteRange Waits for all the requests to complete, giving each one through the range interface as it completes.
CharzBuffer Alternative for toStringz
FilePath This represents a file. Technically, file paths aren't actually strings (for example, on Linux, they need not be valid utf-8, while a D string is supposed to be), even though we almost always use them like that.
FlexibleDelegate Declares a delegate property with several setters to allow for handlers that don't care about the arguments.
IntToStringArgs An int printing function that doesn't need to import Phobos. Can do some of the things std.conv.to and std.format.format do.
LimitedVariant A limited variant to hold just a few types. It is made for the use of packing a small amount of extra data into error messages and some transit across virtual function boundaries.
LoggedMessage DO NOT USE THIS YET IT IS NOT FUNCTIONAL NOR STABLE
NonOverflowingIntBase Does math as a 64 bit number, but saturates at int.min and int.max when converting back to a 32 bit int.
OwnedClass Basically a scope class you can return from a function or embed in another aggregate.
PackedDateTime A packed date/time/datetime representation added for use with LimitedVariant.
PresenceOf This populates a struct from a list of values (or other expressions, but it only looks at the values) based on types of the members, with one exception: bool members.. maybe.
SavedArgument
SchedulableTaskController Gets an object that lets you control a schedulable task (which is a specialization of a fiber) and can be used in an if statement.
SimplifiedUtcTimestamp Basically a Phobos SysTime but standing alone as a simple 64 bit integer (but wrapped) for compatibility with LimitedVariant.
SocketAddress For functions that give you an unknown address, you can use this to hold it.
SourceLocation DO NOT USE THIS YET IT IS NOT FUNCTIONAL NOR STABLE
stringz A wrapper around a const(char)* to indicate that it is a zero-terminated C string.
SynchronizedCircularBuffer This is primarily a helper for the event queues. It is public in the hope it might be useful, but subject to change without notice; I will treat breaking it the same as if it is private. (That said, it is a simple little utility that does its job, so it is unlikely to change much. The biggest change would probably be letting it grow and changing from inline to dynamic array.)
SystemErrorCode A tagged union that holds an error code from system apis, meaning one from Windows GetLastError() or C's errno.
UserProvidedBuffer Some functions that return arrays allow you to provide your own buffer. These are indicated in the type system as UserProvidedBuffer!Type, and you get to decide what you want to happen if the buffer is too small via the [OnOutOfSpace] parameter.

Enums

NameDescription
ByteOrder
EventLoopType The internal types that will be exposed through other api things.
GetFilesResult Note that the order of items called for your delegate is undefined; if you want it sorted, you'll have to collect and sort yourself. But it *might* be sorted by the OS (on Windows, it almost always is), so consider that when choosing a sorting algorithm.
LogLevel DO NOT USE THIS YET IT IS NOT FUNCTIONAL NOR STABLE
OnOutOfSpace Possible policies for [UserProvidedBuffer]s that run out of space.
ThreadToRunIn You can also pass a handle to a specific thread, if you have one.

Templates

NameDescription
OverlappedIoRequest Implementation details of some requests. You shouldn't need to know any of this, the interface is all public.

Manifest constants

NameTypeDescription
dumpParams You can use mixin(dumpParams); to put out a debug print of your current function call w/ params.
populateFromUdas This populates a struct from a list of values (or other expressions, but it only looks at the values) based on types of the members, with one exception: bool members.. maybe.

Global variables

NameTypeDescription
taskUncaughtException void delegate(object.Throwable)

Aliases

NameTypeDescription
AsyncAnonymousPipe AsyncFile Just in case I decide to change the implementation some day.
ErrnoApiException SystemApiException
NativeFileHandle int
NativePipeHandle int
NativeSocketHandle int
NonOverflowingInt NonOverflowingIntBase!(-2147483648,2147483647) Does math as a 64 bit number, but saturates at int.min and int.max when converting back to a 32 bit int.
NonOverflowingUint NonOverflowingIntBase!(0,2147483647) Does math as a 64 bit number, but saturates at int.min and int.max when converting back to a 32 bit int.
typeCast castTo
WindowsApiException SystemApiException The low level use of this would look like throw new WindowsApiException("MsgWaitForMultipleObjectsEx", GetLastError()) but it is meant to be used from higher level things like [Win32Enforce].