Selkie.git | lib/Selkie/Test/ | SnapshotPlatform.rakumod


=begin pod

=head1 NAME

Selkie::Test::SnapshotPlatform - platform fd adapter for snapshot testing

=head1 DESCRIPTION

Internal implementation detail used by C<Selkie::Test::Snapshot>.

=end pod

unit module Selkie::Test::SnapshotPlatform;

use NativeCall;

use Selkie::App::Internal::PosixFD;

# Official Windows MoarVM builds use a private /MT CRT. Snapshot may pass a
# ucrtbase FILE* to the dynamically-linked notcurses library, but it must not
# use that CRT's descriptor operations on MoarVM's fd 1 or 2. The descriptor
# bindings below are POSIX-only and every call is gated by IS-WINDOWS.
our sub snapshot-io-api-spec(Bool:D $is-win --> Map:D) is export(:test) {
	$is-win
		?? Map.new(
			library   => "ucrtbase",
			fopen     => "fopen",
			null-path => "NUL",
		)
		!! Map.new(
			library   => Str,
			fopen     => "fopen",
			fileno    => "fileno",
			dup       => "dup",
			dup2      => "dup2",
			null-path => "/dev/null",
		)
}

our constant IS-WINDOWS is export = $*DISTRO.is-win;
my constant SNAPSHOT-IO-API = snapshot-io-api-spec(IS-WINDOWS);
our constant NULL-PATH is export = SNAPSHOT-IO-API<null-path>;

our sub snapshot-fopen(Str, Str --> Pointer) is export
	is native(SNAPSHOT-IO-API<library>) is symbol(SNAPSHOT-IO-API<fopen>) { * }
our sub snapshot-fclose(Pointer --> int32) is export
	is native(SNAPSHOT-IO-API<library>) is symbol("fclose") { * }
# POSIX-only. NativeCall resolves lazily, and Snapshot gates every call on
# IS-WINDOWS before reaching these process-library bindings.
our sub snapshot-fileno(Pointer --> int32) is export
	is native(Str) is symbol("fileno") { * }
our sub snapshot-dup(int32 $fd --> int32) is export {
	posix-fd-dup($fd)
}
our sub snapshot-dup2(int32 $source, int32 $target --> int32) is export {
	posix-fd-dup2($source, $target)
}

# POSIX-only. NativeCall resolves lazily, and Snapshot gates every call on
# IS-WINDOWS before reaching this binding.
our sub snapshot-setsid(--> int32) is export
	is native(Str) is symbol("setsid") { * }