/// Resolve the prebuilt native library from this package's own installed
/// location so the load works from any working directory and under hardened
/// runtimes. Returns `null` to defer to flutter_rust_bridge's default loader.
///
/// Resolution order:
/// 1. `$nativeLibDirEnv` env var override (dev/test path, no network).
/// 2. Published pub.dev packages stage natives under `lib/src/native/<rid>/`
/// (e.g. `macos-arm64`, `linux-x64`).
/// 3. For local FRB-dev builds the dylib is emitted into
/// `lib/src/{{ module_name }}_bridge_generated/`; that path is searched next.
/// 4. The versioned user-cache directory (`nativeCachedLibPath()`); on a cache
/// miss the native is downloaded and cached (`nativeDownloadAndCacheLibrary()`).
static Future<ExternalLibrary?> _alefResolveExternalLibrary() async {
try {
final envDir = Platform.environment[nativeLibDirEnv];
if (envDir != null && envDir.isNotEmpty) {
final envUri = Uri.directory(envDir);
for (final name in _alefHostLibNames()) {
final libPath = envUri.resolve(name).toFilePath();
if (File(libPath).existsSync() || Directory(libPath).existsSync()) {
return ExternalLibrary.open(libPath);
}
}
}
final packageRoot =
await Isolate.resolvePackageUri(Uri.parse('package:{{ package_name }}/{{ package_name }}.dart'));
if (packageRoot != null) {
final libNames = _alefHostLibNames();
final searchDirs = <Uri>[
if (_alefHostRid() != null) packageRoot.resolve('src/native/${_alefHostRid()}/'),
packageRoot.resolve('src/{{ module_name }}_bridge_generated/'),
];
for (final dir in searchDirs) {
for (final name in libNames) {
final libPath = dir.resolve(name).toFilePath();
if (File(libPath).existsSync() || Directory(libPath).existsSync()) {
return ExternalLibrary.open(libPath);
}
}
}
}
final cachedPath = nativeCachedLibPath();
if (cachedPath != null && File(cachedPath).existsSync()) {
return ExternalLibrary.open(cachedPath);
}
final downloadedPath = await nativeDownloadAndCacheLibrary();
return ExternalLibrary.open(downloadedPath);
} catch (_) {
// Fall through to the default loader on any resolution failure.
}
return null;
}
/// Map the host platform to the pub.dev native staging RID. Returns `null`
/// for unrecognized host triples so the FRB-dev fallback path runs instead.
static String? _alefHostRid() {
final abi = Abi.current();
if (abi == Abi.macosArm64) return 'macos-arm64';
if (abi == Abi.macosX64) return 'macos-x64';
if (abi == Abi.linuxArm64) return 'linux-arm64';
if (abi == Abi.linuxX64) return 'linux-x64';
if (abi == Abi.windowsArm64) return 'windows-arm64';
if (abi == Abi.windowsX64) return 'windows-x64';
return null;
}
static List<String> _alefHostLibNames() {
// The Dart-binding Rust crate is `{stem}-dart` (per the cargo manifest
// template), which produces a cdylib named `lib{stem}_dart.{ext}` on Unix
// and `{stem}_dart.dll` on Windows. On macOS, pub.dev-published packages
// may ship the binary as a Framework bundle (preferred modern packaging)
// — list that first so the loader finds it before the bare dylib.
if (Platform.isMacOS)
return const [
'{{ stem }}_dart.framework',
'lib{{ stem }}_dart.dylib',
];
if (Platform.isWindows) return const ['{{ stem }}_dart.dll'];
return const ['lib{{ stem }}_dart.so'];
}
/// Initialize flutter_rust_bridge
static Future<void> init({
RustLibApi? api,
BaseHandler? handler,
ExternalLibrary? externalLibrary,
bool forceSameCodegenVersion = true,
}) async {
externalLibrary ??= await _alefResolveExternalLibrary();