Adding support for rust core, native shell, using Crux

This commit is contained in:
Pascal de Vink 2025-06-28 14:59:24 +02:00
parent 9adf1410a3
commit ce25bbbfd2
36 changed files with 4119 additions and 1 deletions

Binary file not shown.

2
.cargo/config.toml Normal file
View File

@ -0,0 +1,2 @@
[alias]
xcode = ["bin", "cargo-xcode"]

1
.gitignore vendored
View File

@ -1 +1,2 @@
/target/ /target/
/shared_types/generated/

1414
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,4 +3,21 @@ name = "audio_always_works"
version = "0.1.0" version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [workspace]
members = ["shared", "shared_types"]
resolver = "1"
[workspace.package]
authors = ["Pascal de Vink"]
edition = "2021"
repository = "https://gitea.home.privatevoid.nl/pascaldevink/audio_always_works"
license = "AGPL-3.0-or-later"
rust-version = "1.80"
[workspace.dependencies]
anyhow = "1.0.98"
crux_core = "0.15.0"
serde = "1.0.219"
[workspace.metadata.bin]
cargo-xcode = { version = "=1.7.0" }

View File

@ -0,0 +1,253 @@
// !$*UTF8*$!
{
/* generated with cargo-xcode 1.7.0 */
archiveVersion = 1;
classes = {
};
objectVersion = 53;
objects = {
/* Begin PBXBuildFile section */
CA002181887C121ACC594768 /* Cargo.toml in Sources */ = {isa = PBXBuildFile; fileRef = CAF97371734F3EF4668187A5 /* Cargo.toml */; settings = {COMPILER_FLAGS = "--bin 'audio_always_works'"; }; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
CAF47371734FAC6C1400ACA8 /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.apple.compilers.proxy.script;
dependencyFile = "$(DERIVED_FILE_DIR)/$(CARGO_XCODE_TARGET_ARCH)-$(EXECUTABLE_NAME).d";
filePatterns = "*/Cargo.toml";
fileType = pattern.proxy;
inputFiles = (
);
isEditable = 0;
name = "Cargo project build";
outputFiles = (
"$(OBJECT_FILE_DIR)/$(CARGO_XCODE_TARGET_ARCH)-$(EXECUTABLE_NAME)",
);
script = "# generated with cargo-xcode 1.7.0\nset -xeu;\nexport PATH=\"$HOME/.cargo/bin:$PATH:/usr/local/bin:/opt/homebrew/bin\";\n\nif [ \"${IS_MACCATALYST-NO}\" = YES ]; then\n CARGO_XCODE_TARGET_OS=ios-macabi\nfi\nCARGO_XCODE_TARGET_TRIPLE=\"${CARGO_XCODE_TARGET_ARCH}-apple-${CARGO_XCODE_TARGET_OS}\"\nif [ \"$CARGO_XCODE_TARGET_OS\" != darwin ]; then\n export PATH=\"${PATH/\\/Contents\\/Developer\\/Toolchains\\/XcodeDefault.xctoolchain\\/usr\\/bin:/xcode-provided-ld-cant-link-lSystem-for-the-host-build-script:}\"\nfi\nif [ \"$CARGO_XCODE_BUILD_PROFILE\" == release ]; then\n OTHER_INPUT_FILE_FLAGS=\"${OTHER_INPUT_FILE_FLAGS} --release\"\nfi\n\nif [ \"$ACTION\" = clean ]; then\n cargo clean --verbose --manifest-path=\"$SCRIPT_INPUT_FILE\" ${OTHER_INPUT_FILE_FLAGS} --target=\"${CARGO_XCODE_TARGET_TRIPLE}\";\n rm -f \"$SCRIPT_OUTPUT_FILE_0\"\n exit 0\nfi\ncargo build --verbose --manifest-path=\"$SCRIPT_INPUT_FILE\" --features=\"${CARGO_XCODE_FEATURES:-}\" ${OTHER_INPUT_FILE_FLAGS} --target=\"${CARGO_XCODE_TARGET_TRIPLE}\" || {\n if command -v rustup &> /dev/null; then\n if ! rustup target list --installed | grep -Eq \"${CARGO_XCODE_TARGET_TRIPLE}\"; then\n echo >&2 \"warning: this build requires rustup toolchain for $CARGO_XCODE_TARGET_TRIPLE, but it isn't installed (will try rustup next)\"\n rustup target add \"${CARGO_XCODE_TARGET_TRIPLE}\" || echo >&2 \"warning: can't install $CARGO_XCODE_TARGET_TRIPLE\"\n fi\n fi\n echo >&2 \"error: cargo build failed\"; exit 1; }\n\n# it's too hard to explain Cargo's actual exe path to Xcode build graph, so hardlink to a known-good path instead\nBUILT_SRC=\"${CARGO_TARGET_DIR}/${CARGO_XCODE_TARGET_TRIPLE}/${CARGO_XCODE_BUILD_PROFILE}/${CARGO_XCODE_CARGO_FILE_NAME}\"\nln -f -- \"$BUILT_SRC\" \"$SCRIPT_OUTPUT_FILE_0\" || { echo >&2 \"can't hardlink $BUILT_SRC to $SCRIPT_OUTPUT_FILE_0\"; exit 1; }\n\n# cargo generates a dep file, but for its own path, so append our rename to it\nDEP_FILE_SRC=\"${CARGO_TARGET_DIR}/${CARGO_XCODE_TARGET_TRIPLE}/${CARGO_XCODE_BUILD_PROFILE}/${CARGO_XCODE_CARGO_DEP_FILE_NAME}\"\nif [ -f \"$DEP_FILE_SRC\" ]; then\n DEP_FILE_DST=\"${DERIVED_FILE_DIR}/${CARGO_XCODE_TARGET_ARCH}-${EXECUTABLE_NAME}.d\"\n cp -f \"$DEP_FILE_SRC\" \"$DEP_FILE_DST\" || { echo >&2 \"can't copy $DEP_FILE_SRC to $DEP_FILE_DST\"; exit 1; }\n\n echo >> \"$DEP_FILE_DST\" \"${SCRIPT_OUTPUT_FILE_0/ /\\\\ /}: ${BUILT_SRC/ /\\\\ /}\"\nfi\n\n# lipo script needs to know all the platform-specific files that have been built\n# archs is in the file name, so that paths don't stay around after archs change\n# must match input for LipoScript\nFILE_LIST=\"${DERIVED_FILE_DIR}/${ARCHS}-${EXECUTABLE_NAME}.xcfilelist\"\ntouch \"$FILE_LIST\"\nif ! grep -Eq \"$SCRIPT_OUTPUT_FILE_0\" \"$FILE_LIST\" ; then\n echo >> \"$FILE_LIST\" \"$SCRIPT_OUTPUT_FILE_0\"\nfi\n\necho \"success: $ACTION of $SCRIPT_OUTPUT_FILE_0 for $CARGO_XCODE_TARGET_TRIPLE\"\n";
};
/* End PBXBuildRule section */
/* Begin PBXFileReference section */
CA00E4546D15B49ACB510D63 /* audio_always_works */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = audio_always_works; sourceTree = BUILT_PRODUCTS_DIR; };
CAF97371734F3EF4668187A5 /* Cargo.toml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Cargo.toml; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
CAF07371734FD65BC3C892A8 = {
isa = PBXGroup;
children = (
CAF97371734F3EF4668187A5 /* Cargo.toml */,
CAF17371734F22869D176AE5 /* Products */,
CAF27371734F98AF0B5890DB /* Frameworks */,
);
sourceTree = "<group>";
};
CAF17371734F22869D176AE5 /* Products */ = {
isa = PBXGroup;
children = (
CA00E4546D15B49ACB510D63 /* audio_always_works */,
);
name = Products;
sourceTree = "<group>";
};
CAF27371734F98AF0B5890DB /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
CA00E4546D15121ACC594768 /* audio_always_works-bin */ = {
isa = PBXNativeTarget;
buildConfigurationList = CA001D66D1F3121ACC594768 /* Build configuration list for PBXNativeTarget "audio_always_works-bin" */;
buildPhases = (
CA0095086913121ACC594768 /* Sources */,
CAF57371734FAF6EBB7F357C /* Universal Binary lipo */,
);
buildRules = (
CAF47371734FAC6C1400ACA8 /* PBXBuildRule */,
);
dependencies = (
);
name = "audio_always_works-bin";
productName = audio_always_works;
productReference = CA00E4546D15B49ACB510D63 /* audio_always_works */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
CAF37371734FE04653AD465F /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1500;
TargetAttributes = {
CA00E4546D15121ACC594768 = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = CAF67371734F80E02D6C7F57 /* Build configuration list for PBXProject "audio_always_works" */;
compatibilityVersion = "Xcode 11.4";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = CAF07371734FD65BC3C892A8;
productRefGroup = CAF17371734F22869D176AE5 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
CA00E4546D15121ACC594768 /* audio_always_works-bin */,
);
};
/* End PBXProject section */
/* Begin PBXShellScriptBuildPhase section */
CAF57371734FAF6EBB7F357C /* Universal Binary lipo */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"$(DERIVED_FILE_DIR)/$(ARCHS)-$(EXECUTABLE_NAME).xcfilelist",
);
name = "Universal Binary lipo";
outputFileListPaths = (
);
outputPaths = (
"$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# generated with cargo-xcode 1.7.0\nset -eux;\ntr '\\n' '\\0' < \"$DERIVED_FILE_DIR/$ARCHS-$EXECUTABLE_NAME.xcfilelist\" | xargs -0 lipo -create -output \"$TARGET_BUILD_DIR/$EXECUTABLE_PATH\"\nif [ ${LD_DYLIB_INSTALL_NAME:+1} ]; then\n install_name_tool -id \"$LD_DYLIB_INSTALL_NAME\" \"$TARGET_BUILD_DIR/$EXECUTABLE_PATH\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
CA0095086913121ACC594768 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CA002181887C121ACC594768 /* Cargo.toml in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
CA0050355DF4121ACC594768 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CARGO_XCODE_CARGO_DEP_FILE_NAME = audio_always_works.d;
CARGO_XCODE_CARGO_FILE_NAME = audio_always_works;
PRODUCT_NAME = audio_always_works;
SUPPORTED_PLATFORMS = macosx;
};
name = Release;
};
CA001D9E89C7121ACC594768 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CARGO_XCODE_CARGO_DEP_FILE_NAME = audio_always_works.d;
CARGO_XCODE_CARGO_FILE_NAME = audio_always_works;
PRODUCT_NAME = audio_always_works;
SUPPORTED_PLATFORMS = macosx;
};
name = Debug;
};
CAF7BAE0FD163CC16B37690B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CARGO_TARGET_DIR = "$(PROJECT_TEMP_DIR)/cargo_target";
CARGO_XCODE_BUILD_PROFILE = release;
CARGO_XCODE_FEATURES = "";
"CARGO_XCODE_TARGET_ARCH[arch=arm64*]" = aarch64;
"CARGO_XCODE_TARGET_ARCH[arch=i386]" = i686;
"CARGO_XCODE_TARGET_ARCH[arch=x86_64*]" = x86_64;
"CARGO_XCODE_TARGET_OS[sdk=appletvos*]" = tvos;
"CARGO_XCODE_TARGET_OS[sdk=appletvsimulator*]" = tvos;
"CARGO_XCODE_TARGET_OS[sdk=iphoneos*]" = ios;
"CARGO_XCODE_TARGET_OS[sdk=iphonesimulator*]" = "ios-sim";
"CARGO_XCODE_TARGET_OS[sdk=iphonesimulator*][arch=x86_64*]" = ios;
"CARGO_XCODE_TARGET_OS[sdk=macosx*]" = darwin;
CURRENT_PROJECT_VERSION = 0.1;
MARKETING_VERSION = 0.1.0;
PRODUCT_NAME = audio_always_works;
RUSTUP_TOOLCHAIN = "";
SDKROOT = macosx;
SUPPORTS_MACCATALYST = YES;
};
name = Release;
};
CAF8BAE0FD16228BE02872F8 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CARGO_TARGET_DIR = "$(PROJECT_TEMP_DIR)/cargo_target";
CARGO_XCODE_BUILD_PROFILE = debug;
CARGO_XCODE_FEATURES = "";
"CARGO_XCODE_TARGET_ARCH[arch=arm64*]" = aarch64;
"CARGO_XCODE_TARGET_ARCH[arch=i386]" = i686;
"CARGO_XCODE_TARGET_ARCH[arch=x86_64*]" = x86_64;
"CARGO_XCODE_TARGET_OS[sdk=appletvos*]" = tvos;
"CARGO_XCODE_TARGET_OS[sdk=appletvsimulator*]" = tvos;
"CARGO_XCODE_TARGET_OS[sdk=iphoneos*]" = ios;
"CARGO_XCODE_TARGET_OS[sdk=iphonesimulator*]" = "ios-sim";
"CARGO_XCODE_TARGET_OS[sdk=iphonesimulator*][arch=x86_64*]" = ios;
"CARGO_XCODE_TARGET_OS[sdk=macosx*]" = darwin;
CURRENT_PROJECT_VERSION = 0.1;
MARKETING_VERSION = 0.1.0;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = audio_always_works;
RUSTUP_TOOLCHAIN = "";
SDKROOT = macosx;
SUPPORTS_MACCATALYST = YES;
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
CA001D66D1F3121ACC594768 /* Build configuration list for PBXNativeTarget "audio_always_works-bin" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CA0050355DF4121ACC594768 /* Release */,
CA001D9E89C7121ACC594768 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CAF67371734F80E02D6C7F57 /* Build configuration list for PBXProject "audio_always_works" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CAF7BAE0FD163CC16B37690B /* Release */,
CAF8BAE0FD16228BE02872F8 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = CAF37371734FE04653AD465F /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>audio_always_works-bin.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,475 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
00E8861E16817C505A2ECDE8 /* libshared_static.a.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E85E5699EC0D4ACC3ECF08C7 /* libshared_static.a.a */; };
46FF5D3E091859708BFB695D /* AudioAlwaysWorksApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B12612A4D67D20B81EB2E /* AudioAlwaysWorksApp.swift */; };
7F9D6E2F706B4395EB6601CA /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB4929ACDBDFEE04D6BD1450 /* ContentView.swift */; };
959935D0681AECAF2C9D286E /* shared.udl in Sources */ = {isa = PBXBuildFile; fileRef = AC29F76997F3C99B413D302C /* shared.udl */; };
C81403257A4C05A09F8D4204 /* core.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CE412001E7794AD347EBD19 /* core.swift */; };
D56F70A0151CDB9B5FFDF152 /* SharedTypes in Frameworks */ = {isa = PBXBuildFile; productRef = 0CC389A097C62FD0236B24A7 /* SharedTypes */; };
EBABE42AB688D7559072487D /* (null) in Resources */ = {isa = PBXBuildFile; fileRef = 950989282E252A7B9B3FD161; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
E1379C8142E9E6C9D55EE54C /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.apple.compilers.proxy.script;
filePatterns = "*.udl";
fileType = pattern.proxy;
isEditable = 1;
name = "Generate FFI";
outputFiles = (
"$(PROJECT_DIR)/generated/$(INPUT_FILE_BASE).swift",
"$(PROJECT_DIR)/generated/$(INPUT_FILE_BASE)FFI.h",
);
outputFilesCompilerFlags = (
);
runOncePerArchitecture = 0;
script = "#!/bin/bash\nset -e\n\n# Skip during indexing phase in XCode 13+\nif [ \"$ACTION\" == \"indexbuild\" ]; then\n echo \"Not building *.udl files during indexing.\"\n exit 0\nfi\n\n# Skip for preview builds\nif [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then\n echo \"Not building *.udl files during preview builds.\"\n exit 0\nfi\n\ncd \"${INPUT_FILE_DIR}/..\"\n\"${BUILD_DIR}/${CONFIGURATION}/uniffi-bindgen\" generate \"src/${INPUT_FILE_NAME}\" --language swift --out-dir \"${PROJECT_DIR}/generated\"\n";
};
/* End PBXBuildRule section */
/* Begin PBXContainerItemProxy section */
2691CEA93CAFF0B4913D0104 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 58D1273A2F85C7E8A1B7A368 /* Shared */;
proxyType = 1;
remoteGlobalIDString = CA02FA85CE9E4296ADE0F606;
remoteInfo = "uniffi-bindgen-bin";
};
36A596DB7199CBE221785B4C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 58D1273A2F85C7E8A1B7A368 /* Shared */;
proxyType = 2;
remoteGlobalIDString = CA02FA85CE9E8109328FB0D5;
remoteInfo = "uniffi-bindgen-bin";
};
6C009F766D2C7D18C5B54FBD /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 58D1273A2F85C7E8A1B7A368 /* Shared */;
proxyType = 2;
remoteGlobalIDString = CA0049BF7D4FFB09138082B7;
remoteInfo = "shared-staticlib";
};
84766557D1D0D528121CE64B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 58D1273A2F85C7E8A1B7A368 /* Shared */;
proxyType = 1;
remoteGlobalIDString = CA0049BF7D4FD346A0A05154;
remoteInfo = "shared-staticlib";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
2CE412001E7794AD347EBD19 /* core.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = core.swift; sourceTree = "<group>"; };
462254CE9DE6D2EC30FF3A86 /* AudioAlwaysWorks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AudioAlwaysWorks.app; sourceTree = BUILT_PRODUCTS_DIR; };
58D1273A2F85C7E8A1B7A368 /* Shared */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Shared; path = ../shared/shared.xcodeproj; sourceTree = "<group>"; };
875EDCC9B68900ADF353E8B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
AC29F76997F3C99B413D302C /* shared.udl */ = {isa = PBXFileReference; path = shared.udl; sourceTree = "<group>"; };
B53B12612A4D67D20B81EB2E /* AudioAlwaysWorksApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioAlwaysWorksApp.swift; sourceTree = "<group>"; };
BB4929ACDBDFEE04D6BD1450 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
BF6D1C0DFE7DE3DFA9713895 /* SharedTypes */ = {isa = PBXFileReference; lastKnownFileType = folder; name = SharedTypes; path = ../shared_types/generated/swift/SharedTypes; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
CB8C2D766232756B7B816714 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
00E8861E16817C505A2ECDE8 /* libshared_static.a.a in Frameworks */,
D56F70A0151CDB9B5FFDF152 /* SharedTypes in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
00F1A536CE165C8B63EE5233 /* Products */ = {
isa = PBXGroup;
children = (
950989282E252A7B9B3FD161,
E85E5699EC0D4ACC3ECF08C7 /* libshared_static.a.a */,
);
name = Products;
sourceTree = "<group>";
};
145344B309F5A46FC5F95985 /* Projects */ = {
isa = PBXGroup;
children = (
58D1273A2F85C7E8A1B7A368 /* Shared */,
);
name = Projects;
sourceTree = "<group>";
};
3F7AF5C4695691A01288E08F /* Products */ = {
isa = PBXGroup;
children = (
462254CE9DE6D2EC30FF3A86 /* AudioAlwaysWorks.app */,
);
name = Products;
sourceTree = "<group>";
};
454476D2D91CEEB0D4374C0E /* src */ = {
isa = PBXGroup;
children = (
AC29F76997F3C99B413D302C /* shared.udl */,
);
name = src;
path = ../shared/src;
sourceTree = "<group>";
};
46AF0F5B2FE283356AB99974 = {
isa = PBXGroup;
children = (
66C1A14C5F509EC6A51BE396 /* AudioAlwaysWorks */,
94903FA415C62EF670977E13 /* Packages */,
454476D2D91CEEB0D4374C0E /* src */,
3F7AF5C4695691A01288E08F /* Products */,
145344B309F5A46FC5F95985 /* Projects */,
);
sourceTree = "<group>";
};
66C1A14C5F509EC6A51BE396 /* AudioAlwaysWorks */ = {
isa = PBXGroup;
children = (
B53B12612A4D67D20B81EB2E /* AudioAlwaysWorksApp.swift */,
BB4929ACDBDFEE04D6BD1450 /* ContentView.swift */,
2CE412001E7794AD347EBD19 /* core.swift */,
875EDCC9B68900ADF353E8B9 /* Info.plist */,
);
path = AudioAlwaysWorks;
sourceTree = "<group>";
};
94903FA415C62EF670977E13 /* Packages */ = {
isa = PBXGroup;
children = (
BF6D1C0DFE7DE3DFA9713895 /* SharedTypes */,
);
name = Packages;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
F6EFF5C544F3BC9C6A9B8E5C /* AudioAlwaysWorks */ = {
isa = PBXNativeTarget;
buildConfigurationList = 8E8D2F01A9911444D404B5B6 /* Build configuration list for PBXNativeTarget "AudioAlwaysWorks" */;
buildPhases = (
80164FD90B2E283AA182832A /* Sources */,
C48990381B7BD8C84B9108F1 /* Resources */,
CB8C2D766232756B7B816714 /* Frameworks */,
);
buildRules = (
E1379C8142E9E6C9D55EE54C /* PBXBuildRule */,
);
dependencies = (
6FB8261A37F6A141EDC63F61 /* PBXTargetDependency */,
6FF5790D3621F6EBB9C2C7EA /* PBXTargetDependency */,
);
name = AudioAlwaysWorks;
packageProductDependencies = (
0CC389A097C62FD0236B24A7 /* SharedTypes */,
);
productName = AudioAlwaysWorks;
productReference = 462254CE9DE6D2EC30FF3A86 /* AudioAlwaysWorks.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
CD31D51CAEA76326143638AA /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1430;
TargetAttributes = {
};
};
buildConfigurationList = 96DE4556CF1251C69E040258 /* Build configuration list for PBXProject "AudioAlwaysWorks" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
Base,
en,
);
mainGroup = 46AF0F5B2FE283356AB99974;
minimizedProjectReferenceProxies = 1;
packageReferences = (
6FABBE062C9537623FCDDE8A /* XCLocalSwiftPackageReference "../shared_types/generated/swift/SharedTypes" */,
);
preferredProjectObjectVersion = 54;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 00F1A536CE165C8B63EE5233 /* Products */;
ProjectRef = 58D1273A2F85C7E8A1B7A368 /* Shared */;
},
);
projectRoot = "";
targets = (
F6EFF5C544F3BC9C6A9B8E5C /* AudioAlwaysWorks */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
950989282E252A7B9B3FD161 = {
isa = PBXReferenceProxy;
remoteRef = 36A596DB7199CBE221785B4C /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
E85E5699EC0D4ACC3ECF08C7 /* libshared_static.a.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libshared_static.a.a;
remoteRef = 6C009F766D2C7D18C5B54FBD /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
C48990381B7BD8C84B9108F1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
EBABE42AB688D7559072487D /* (null) in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
80164FD90B2E283AA182832A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
46FF5D3E091859708BFB695D /* AudioAlwaysWorksApp.swift in Sources */,
7F9D6E2F706B4395EB6601CA /* ContentView.swift in Sources */,
C81403257A4C05A09F8D4204 /* core.swift in Sources */,
959935D0681AECAF2C9D286E /* shared.udl in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
6FB8261A37F6A141EDC63F61 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "uniffi-bindgen-bin";
targetProxy = 2691CEA93CAFF0B4913D0104 /* PBXContainerItemProxy */;
};
6FF5790D3621F6EBB9C2C7EA /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "shared-staticlib";
targetProxy = 84766557D1D0D528121CE64B /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
AB847326C9251A1ACEC296CC /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
};
name = Release;
};
B48AFAF2195277CA789A64BC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
INFOPLIST_FILE = AudioAlwaysWorks/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15.5;
OTHER_LDFLAGS = (
"-w",
"-ObjC",
);
PRODUCT_BUNDLE_IDENTIFIER = nl.pascaldevink.audio_always_works.AudioAlwaysWorks;
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = generated/sharedFFI.h;
};
name = Debug;
};
D0294531C3F73284ABF61EC5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"DEBUG=1",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
E5029E47918032BE5848DC2E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
COMBINE_HIDPI_IMAGES = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
INFOPLIST_FILE = AudioAlwaysWorks/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15.5;
OTHER_LDFLAGS = (
"-w",
"-ObjC",
);
PRODUCT_BUNDLE_IDENTIFIER = nl.pascaldevink.audio_always_works.AudioAlwaysWorks;
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = generated/sharedFFI.h;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
8E8D2F01A9911444D404B5B6 /* Build configuration list for PBXNativeTarget "AudioAlwaysWorks" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B48AFAF2195277CA789A64BC /* Debug */,
E5029E47918032BE5848DC2E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
96DE4556CF1251C69E040258 /* Build configuration list for PBXProject "AudioAlwaysWorks" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D0294531C3F73284ABF61EC5 /* Debug */,
AB847326C9251A1ACEC296CC /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
/* Begin XCLocalSwiftPackageReference section */
6FABBE062C9537623FCDDE8A /* XCLocalSwiftPackageReference "../shared_types/generated/swift/SharedTypes" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = ../shared_types/generated/swift/SharedTypes;
};
/* End XCLocalSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
0CC389A097C62FD0236B24A7 /* SharedTypes */ = {
isa = XCSwiftPackageProductDependency;
productName = SharedTypes;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = CD31D51CAEA76326143638AA /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>AudioAlwaysWorks.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,10 @@
import SwiftUI
@main
struct AudioAlwaysWorksApp: App {
var body: some Scene {
WindowGroup {
ContentView(core: Core())
}
}
}

View File

@ -0,0 +1,47 @@
import SharedTypes
import SwiftUI
struct ContentView: View {
@ObservedObject var core: Core
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text(core.view.selected_input_device)
Text(core.view.selected_output_device)
}
}
}
struct ActionButton: View {
var label: String
var color: Color
var action: () -> Void
init(label: String, color: Color, action: @escaping () -> Void) {
self.label = label
self.color = color
self.action = action
}
var body: some View {
Button(action: action) {
Text(label)
.fontWeight(.bold)
.font(.body)
.padding(EdgeInsets(top: 10, leading: 15, bottom: 10, trailing: 15))
.background(color)
.cornerRadius(10)
.foregroundColor(.white)
.padding()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(core: Core())
}
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>UILaunchScreen</key>
<dict/>
</dict>
</plist>

View File

@ -0,0 +1,27 @@
import Foundation
import SharedTypes
@MainActor
class Core: ObservableObject {
@Published var view: ViewModel
init() {
self.view = try! .bincodeDeserialize(input: [UInt8](AudioAlwaysWorks.view()))
}
func update(_ event: Event) {
let effects = [UInt8](processEvent(Data(try! event.bincodeSerialize())))
let requests: [Request] = try! .bincodeDeserialize(input: effects)
for request in requests {
processEffect(request)
}
}
func processEffect(_ request: Request) {
switch request.effect {
case .render:
view = try! .bincodeDeserialize(input: [UInt8](AudioAlwaysWorks.view()))
}
}
}

View File

@ -0,0 +1,537 @@
// This file was autogenerated by some hot garbage in the `uniffi` crate.
// Trust me, you don't want to mess with it!
// swiftlint:disable all
import Foundation
// Depending on the consumer's build setup, the low-level FFI code
// might be in a separate module, or it might be compiled inline into
// this module. This is a bit of light hackery to work with both.
#if canImport(sharedFFI)
import sharedFFI
#endif
fileprivate extension RustBuffer {
// Allocate a new buffer, copying the contents of a `UInt8` array.
init(bytes: [UInt8]) {
let rbuf = bytes.withUnsafeBufferPointer { ptr in
RustBuffer.from(ptr)
}
self.init(capacity: rbuf.capacity, len: rbuf.len, data: rbuf.data)
}
static func empty() -> RustBuffer {
RustBuffer(capacity: 0, len:0, data: nil)
}
static func from(_ ptr: UnsafeBufferPointer<UInt8>) -> RustBuffer {
try! rustCall { ffi_shared_rustbuffer_from_bytes(ForeignBytes(bufferPointer: ptr), $0) }
}
// Frees the buffer in place.
// The buffer must not be used after this is called.
func deallocate() {
try! rustCall { ffi_shared_rustbuffer_free(self, $0) }
}
}
fileprivate extension ForeignBytes {
init(bufferPointer: UnsafeBufferPointer<UInt8>) {
self.init(len: Int32(bufferPointer.count), data: bufferPointer.baseAddress)
}
}
// For every type used in the interface, we provide helper methods for conveniently
// lifting and lowering that type from C-compatible data, and for reading and writing
// values of that type in a buffer.
// Helper classes/extensions that don't change.
// Someday, this will be in a library of its own.
fileprivate extension Data {
init(rustBuffer: RustBuffer) {
self.init(
bytesNoCopy: rustBuffer.data!,
count: Int(rustBuffer.len),
deallocator: .none
)
}
}
// Define reader functionality. Normally this would be defined in a class or
// struct, but we use standalone functions instead in order to make external
// types work.
//
// With external types, one swift source file needs to be able to call the read
// method on another source file's FfiConverter, but then what visibility
// should Reader have?
// - If Reader is fileprivate, then this means the read() must also
// be fileprivate, which doesn't work with external types.
// - If Reader is internal/public, we'll get compile errors since both source
// files will try define the same type.
//
// Instead, the read() method and these helper functions input a tuple of data
fileprivate func createReader(data: Data) -> (data: Data, offset: Data.Index) {
(data: data, offset: 0)
}
// Reads an integer at the current offset, in big-endian order, and advances
// the offset on success. Throws if reading the integer would move the
// offset past the end of the buffer.
fileprivate func readInt<T: FixedWidthInteger>(_ reader: inout (data: Data, offset: Data.Index)) throws -> T {
let range = reader.offset..<reader.offset + MemoryLayout<T>.size
guard reader.data.count >= range.upperBound else {
throw UniffiInternalError.bufferOverflow
}
if T.self == UInt8.self {
let value = reader.data[reader.offset]
reader.offset += 1
return value as! T
}
var value: T = 0
let _ = withUnsafeMutableBytes(of: &value, { reader.data.copyBytes(to: $0, from: range)})
reader.offset = range.upperBound
return value.bigEndian
}
// Reads an arbitrary number of bytes, to be used to read
// raw bytes, this is useful when lifting strings
fileprivate func readBytes(_ reader: inout (data: Data, offset: Data.Index), count: Int) throws -> Array<UInt8> {
let range = reader.offset..<(reader.offset+count)
guard reader.data.count >= range.upperBound else {
throw UniffiInternalError.bufferOverflow
}
var value = [UInt8](repeating: 0, count: count)
value.withUnsafeMutableBufferPointer({ buffer in
reader.data.copyBytes(to: buffer, from: range)
})
reader.offset = range.upperBound
return value
}
// Reads a float at the current offset.
fileprivate func readFloat(_ reader: inout (data: Data, offset: Data.Index)) throws -> Float {
return Float(bitPattern: try readInt(&reader))
}
// Reads a float at the current offset.
fileprivate func readDouble(_ reader: inout (data: Data, offset: Data.Index)) throws -> Double {
return Double(bitPattern: try readInt(&reader))
}
// Indicates if the offset has reached the end of the buffer.
fileprivate func hasRemaining(_ reader: (data: Data, offset: Data.Index)) -> Bool {
return reader.offset < reader.data.count
}
// Define writer functionality. Normally this would be defined in a class or
// struct, but we use standalone functions instead in order to make external
// types work. See the above discussion on Readers for details.
fileprivate func createWriter() -> [UInt8] {
return []
}
fileprivate func writeBytes<S>(_ writer: inout [UInt8], _ byteArr: S) where S: Sequence, S.Element == UInt8 {
writer.append(contentsOf: byteArr)
}
// Writes an integer in big-endian order.
//
// Warning: make sure what you are trying to write
// is in the correct type!
fileprivate func writeInt<T: FixedWidthInteger>(_ writer: inout [UInt8], _ value: T) {
var value = value.bigEndian
withUnsafeBytes(of: &value) { writer.append(contentsOf: $0) }
}
fileprivate func writeFloat(_ writer: inout [UInt8], _ value: Float) {
writeInt(&writer, value.bitPattern)
}
fileprivate func writeDouble(_ writer: inout [UInt8], _ value: Double) {
writeInt(&writer, value.bitPattern)
}
// Protocol for types that transfer other types across the FFI. This is
// analogous to the Rust trait of the same name.
fileprivate protocol FfiConverter {
associatedtype FfiType
associatedtype SwiftType
static func lift(_ value: FfiType) throws -> SwiftType
static func lower(_ value: SwiftType) -> FfiType
static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType
static func write(_ value: SwiftType, into buf: inout [UInt8])
}
// Types conforming to `Primitive` pass themselves directly over the FFI.
fileprivate protocol FfiConverterPrimitive: FfiConverter where FfiType == SwiftType { }
extension FfiConverterPrimitive {
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public static func lift(_ value: FfiType) throws -> SwiftType {
return value
}
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public static func lower(_ value: SwiftType) -> FfiType {
return value
}
}
// Types conforming to `FfiConverterRustBuffer` lift and lower into a `RustBuffer`.
// Used for complex types where it's hard to write a custom lift/lower.
fileprivate protocol FfiConverterRustBuffer: FfiConverter where FfiType == RustBuffer {}
extension FfiConverterRustBuffer {
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public static func lift(_ buf: RustBuffer) throws -> SwiftType {
var reader = createReader(data: Data(rustBuffer: buf))
let value = try read(from: &reader)
if hasRemaining(reader) {
throw UniffiInternalError.incompleteData
}
buf.deallocate()
return value
}
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public static func lower(_ value: SwiftType) -> RustBuffer {
var writer = createWriter()
write(value, into: &writer)
return RustBuffer(bytes: writer)
}
}
// An error type for FFI errors. These errors occur at the UniFFI level, not
// the library level.
fileprivate enum UniffiInternalError: LocalizedError {
case bufferOverflow
case incompleteData
case unexpectedOptionalTag
case unexpectedEnumCase
case unexpectedNullPointer
case unexpectedRustCallStatusCode
case unexpectedRustCallError
case unexpectedStaleHandle
case rustPanic(_ message: String)
public var errorDescription: String? {
switch self {
case .bufferOverflow: return "Reading the requested value would read past the end of the buffer"
case .incompleteData: return "The buffer still has data after lifting its containing value"
case .unexpectedOptionalTag: return "Unexpected optional tag; should be 0 or 1"
case .unexpectedEnumCase: return "Raw enum value doesn't match any cases"
case .unexpectedNullPointer: return "Raw pointer value was null"
case .unexpectedRustCallStatusCode: return "Unexpected RustCallStatus code"
case .unexpectedRustCallError: return "CALL_ERROR but no errorClass specified"
case .unexpectedStaleHandle: return "The object in the handle map has been dropped already"
case let .rustPanic(message): return message
}
}
}
fileprivate extension NSLock {
func withLock<T>(f: () throws -> T) rethrows -> T {
self.lock()
defer { self.unlock() }
return try f()
}
}
fileprivate let CALL_SUCCESS: Int8 = 0
fileprivate let CALL_ERROR: Int8 = 1
fileprivate let CALL_UNEXPECTED_ERROR: Int8 = 2
fileprivate let CALL_CANCELLED: Int8 = 3
fileprivate extension RustCallStatus {
init() {
self.init(
code: CALL_SUCCESS,
errorBuf: RustBuffer.init(
capacity: 0,
len: 0,
data: nil
)
)
}
}
private func rustCall<T>(_ callback: (UnsafeMutablePointer<RustCallStatus>) -> T) throws -> T {
let neverThrow: ((RustBuffer) throws -> Never)? = nil
return try makeRustCall(callback, errorHandler: neverThrow)
}
private func rustCallWithError<T, E: Swift.Error>(
_ errorHandler: @escaping (RustBuffer) throws -> E,
_ callback: (UnsafeMutablePointer<RustCallStatus>) -> T) throws -> T {
try makeRustCall(callback, errorHandler: errorHandler)
}
private func makeRustCall<T, E: Swift.Error>(
_ callback: (UnsafeMutablePointer<RustCallStatus>) -> T,
errorHandler: ((RustBuffer) throws -> E)?
) throws -> T {
uniffiEnsureSharedInitialized()
var callStatus = RustCallStatus.init()
let returnedVal = callback(&callStatus)
try uniffiCheckCallStatus(callStatus: callStatus, errorHandler: errorHandler)
return returnedVal
}
private func uniffiCheckCallStatus<E: Swift.Error>(
callStatus: RustCallStatus,
errorHandler: ((RustBuffer) throws -> E)?
) throws {
switch callStatus.code {
case CALL_SUCCESS:
return
case CALL_ERROR:
if let errorHandler = errorHandler {
throw try errorHandler(callStatus.errorBuf)
} else {
callStatus.errorBuf.deallocate()
throw UniffiInternalError.unexpectedRustCallError
}
case CALL_UNEXPECTED_ERROR:
// When the rust code sees a panic, it tries to construct a RustBuffer
// with the message. But if that code panics, then it just sends back
// an empty buffer.
if callStatus.errorBuf.len > 0 {
throw UniffiInternalError.rustPanic(try FfiConverterString.lift(callStatus.errorBuf))
} else {
callStatus.errorBuf.deallocate()
throw UniffiInternalError.rustPanic("Rust panic")
}
case CALL_CANCELLED:
fatalError("Cancellation not supported yet")
default:
throw UniffiInternalError.unexpectedRustCallStatusCode
}
}
private func uniffiTraitInterfaceCall<T>(
callStatus: UnsafeMutablePointer<RustCallStatus>,
makeCall: () throws -> T,
writeReturn: (T) -> ()
) {
do {
try writeReturn(makeCall())
} catch let error {
callStatus.pointee.code = CALL_UNEXPECTED_ERROR
callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error))
}
}
private func uniffiTraitInterfaceCallWithError<T, E>(
callStatus: UnsafeMutablePointer<RustCallStatus>,
makeCall: () throws -> T,
writeReturn: (T) -> (),
lowerError: (E) -> RustBuffer
) {
do {
try writeReturn(makeCall())
} catch let error as E {
callStatus.pointee.code = CALL_ERROR
callStatus.pointee.errorBuf = lowerError(error)
} catch {
callStatus.pointee.code = CALL_UNEXPECTED_ERROR
callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error))
}
}
fileprivate final class UniffiHandleMap<T>: @unchecked Sendable {
// All mutation happens with this lock held, which is why we implement @unchecked Sendable.
private let lock = NSLock()
private var map: [UInt64: T] = [:]
private var currentHandle: UInt64 = 1
func insert(obj: T) -> UInt64 {
lock.withLock {
let handle = currentHandle
currentHandle += 1
map[handle] = obj
return handle
}
}
func get(handle: UInt64) throws -> T {
try lock.withLock {
guard let obj = map[handle] else {
throw UniffiInternalError.unexpectedStaleHandle
}
return obj
}
}
@discardableResult
func remove(handle: UInt64) throws -> T {
try lock.withLock {
guard let obj = map.removeValue(forKey: handle) else {
throw UniffiInternalError.unexpectedStaleHandle
}
return obj
}
}
var count: Int {
get {
map.count
}
}
}
// Public interface members begin here.
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterUInt32: FfiConverterPrimitive {
typealias FfiType = UInt32
typealias SwiftType = UInt32
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt32 {
return try lift(readInt(&buf))
}
public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
writeInt(&buf, lower(value))
}
}
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterString: FfiConverter {
typealias SwiftType = String
typealias FfiType = RustBuffer
public static func lift(_ value: RustBuffer) throws -> String {
defer {
value.deallocate()
}
if value.data == nil {
return String()
}
let bytes = UnsafeBufferPointer<UInt8>(start: value.data!, count: Int(value.len))
return String(bytes: bytes, encoding: String.Encoding.utf8)!
}
public static func lower(_ value: String) -> RustBuffer {
return value.utf8CString.withUnsafeBufferPointer { ptr in
// The swift string gives us int8_t, we want uint8_t.
ptr.withMemoryRebound(to: UInt8.self) { ptr in
// The swift string gives us a trailing null byte, we don't want it.
let buf = UnsafeBufferPointer(rebasing: ptr.prefix(upTo: ptr.count - 1))
return RustBuffer.from(buf)
}
}
}
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> String {
let len: Int32 = try readInt(&buf)
return String(bytes: try readBytes(&buf, count: Int(len)), encoding: String.Encoding.utf8)!
}
public static func write(_ value: String, into buf: inout [UInt8]) {
let len = Int32(value.utf8.count)
writeInt(&buf, len)
writeBytes(&buf, value.utf8)
}
}
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterData: FfiConverterRustBuffer {
typealias SwiftType = Data
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Data {
let len: Int32 = try readInt(&buf)
return Data(try readBytes(&buf, count: Int(len)))
}
public static func write(_ value: Data, into buf: inout [UInt8]) {
let len = Int32(value.count)
writeInt(&buf, len)
writeBytes(&buf, value)
}
}
public func handleResponse(_ id: UInt32, _ res: Data) -> Data {
return try! FfiConverterData.lift(try! rustCall() {
uniffi_shared_fn_func_handle_response(
FfiConverterUInt32.lower(id),
FfiConverterData.lower(res),$0
)
})
}
public func processEvent(_ msg: Data) -> Data {
return try! FfiConverterData.lift(try! rustCall() {
uniffi_shared_fn_func_process_event(
FfiConverterData.lower(msg),$0
)
})
}
public func view() -> Data {
return try! FfiConverterData.lift(try! rustCall() {
uniffi_shared_fn_func_view($0
)
})
}
private enum InitializationResult {
case ok
case contractVersionMismatch
case apiChecksumMismatch
}
// Use a global variable to perform the versioning checks. Swift ensures that
// the code inside is only computed once.
private let initializationResult: InitializationResult = {
// Get the bindings contract version from our ComponentInterface
let bindings_contract_version = 29
// Get the scaffolding contract version by calling the into the dylib
let scaffolding_contract_version = ffi_shared_uniffi_contract_version()
if bindings_contract_version != scaffolding_contract_version {
return InitializationResult.contractVersionMismatch
}
if (uniffi_shared_checksum_func_handle_response() != 38599) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_shared_checksum_func_process_event() != 35444) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_shared_checksum_func_view() != 57786) {
return InitializationResult.apiChecksumMismatch
}
return InitializationResult.ok
}()
// Make the ensure init function public so that other modules which have external type references to
// our types can call it.
public func uniffiEnsureSharedInitialized() {
switch initializationResult {
case .ok:
break
case .contractVersionMismatch:
fatalError("UniFFI contract version mismatch: try cleaning and rebuilding your project")
case .apiChecksumMismatch:
fatalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
}
}
// swiftlint:enable all

574
macOS/generated/sharedFFI.h Normal file
View File

@ -0,0 +1,574 @@
// This file was autogenerated by some hot garbage in the `uniffi` crate.
// Trust me, you don't want to mess with it!
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
// The following structs are used to implement the lowest level
// of the FFI, and thus useful to multiple uniffied crates.
// We ensure they are declared exactly once, with a header guard, UNIFFI_SHARED_H.
#ifdef UNIFFI_SHARED_H
// We also try to prevent mixing versions of shared uniffi header structs.
// If you add anything to the #else block, you must increment the version suffix in UNIFFI_SHARED_HEADER_V4
#ifndef UNIFFI_SHARED_HEADER_V4
#error Combining helper code from multiple versions of uniffi is not supported
#endif // ndef UNIFFI_SHARED_HEADER_V4
#else
#define UNIFFI_SHARED_H
#define UNIFFI_SHARED_HEADER_V4
// ⚠️ Attention: If you change this #else block (ending in `#endif // def UNIFFI_SHARED_H`) you *must* ⚠️
// ⚠️ increment the version suffix in all instances of UNIFFI_SHARED_HEADER_V4 in this file. ⚠️
typedef struct RustBuffer
{
uint64_t capacity;
uint64_t len;
uint8_t *_Nullable data;
} RustBuffer;
typedef struct ForeignBytes
{
int32_t len;
const uint8_t *_Nullable data;
} ForeignBytes;
// Error definitions
typedef struct RustCallStatus {
int8_t code;
RustBuffer errorBuf;
} RustCallStatus;
// ⚠️ Attention: If you change this #else block (ending in `#endif // def UNIFFI_SHARED_H`) you *must* ⚠️
// ⚠️ increment the version suffix in all instances of UNIFFI_SHARED_HEADER_V4 in this file. ⚠️
#endif // def UNIFFI_SHARED_H
#ifndef UNIFFI_FFIDEF_RUST_FUTURE_CONTINUATION_CALLBACK
#define UNIFFI_FFIDEF_RUST_FUTURE_CONTINUATION_CALLBACK
typedef void (*UniffiRustFutureContinuationCallback)(uint64_t, int8_t
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_FREE
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_FREE
typedef void (*UniffiForeignFutureFree)(uint64_t
);
#endif
#ifndef UNIFFI_FFIDEF_CALLBACK_INTERFACE_FREE
#define UNIFFI_FFIDEF_CALLBACK_INTERFACE_FREE
typedef void (*UniffiCallbackInterfaceFree)(uint64_t
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE
#define UNIFFI_FFIDEF_FOREIGN_FUTURE
typedef struct UniffiForeignFuture {
uint64_t handle;
UniffiForeignFutureFree _Nonnull free;
} UniffiForeignFuture;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U8
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U8
typedef struct UniffiForeignFutureStructU8 {
uint8_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructU8;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U8
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U8
typedef void (*UniffiForeignFutureCompleteU8)(uint64_t, UniffiForeignFutureStructU8
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I8
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I8
typedef struct UniffiForeignFutureStructI8 {
int8_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructI8;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I8
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I8
typedef void (*UniffiForeignFutureCompleteI8)(uint64_t, UniffiForeignFutureStructI8
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U16
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U16
typedef struct UniffiForeignFutureStructU16 {
uint16_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructU16;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U16
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U16
typedef void (*UniffiForeignFutureCompleteU16)(uint64_t, UniffiForeignFutureStructU16
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I16
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I16
typedef struct UniffiForeignFutureStructI16 {
int16_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructI16;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I16
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I16
typedef void (*UniffiForeignFutureCompleteI16)(uint64_t, UniffiForeignFutureStructI16
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U32
typedef struct UniffiForeignFutureStructU32 {
uint32_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructU32;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U32
typedef void (*UniffiForeignFutureCompleteU32)(uint64_t, UniffiForeignFutureStructU32
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I32
typedef struct UniffiForeignFutureStructI32 {
int32_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructI32;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I32
typedef void (*UniffiForeignFutureCompleteI32)(uint64_t, UniffiForeignFutureStructI32
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_U64
typedef struct UniffiForeignFutureStructU64 {
uint64_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructU64;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_U64
typedef void (*UniffiForeignFutureCompleteU64)(uint64_t, UniffiForeignFutureStructU64
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_I64
typedef struct UniffiForeignFutureStructI64 {
int64_t returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructI64;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_I64
typedef void (*UniffiForeignFutureCompleteI64)(uint64_t, UniffiForeignFutureStructI64
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_F32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_F32
typedef struct UniffiForeignFutureStructF32 {
float returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructF32;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F32
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F32
typedef void (*UniffiForeignFutureCompleteF32)(uint64_t, UniffiForeignFutureStructF32
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_F64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_F64
typedef struct UniffiForeignFutureStructF64 {
double returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructF64;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F64
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_F64
typedef void (*UniffiForeignFutureCompleteF64)(uint64_t, UniffiForeignFutureStructF64
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_POINTER
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_POINTER
typedef struct UniffiForeignFutureStructPointer {
void*_Nonnull returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructPointer;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_POINTER
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_POINTER
typedef void (*UniffiForeignFutureCompletePointer)(uint64_t, UniffiForeignFutureStructPointer
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_RUST_BUFFER
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_RUST_BUFFER
typedef struct UniffiForeignFutureStructRustBuffer {
RustBuffer returnValue;
RustCallStatus callStatus;
} UniffiForeignFutureStructRustBuffer;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_RUST_BUFFER
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_RUST_BUFFER
typedef void (*UniffiForeignFutureCompleteRustBuffer)(uint64_t, UniffiForeignFutureStructRustBuffer
);
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_VOID
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_STRUCT_VOID
typedef struct UniffiForeignFutureStructVoid {
RustCallStatus callStatus;
} UniffiForeignFutureStructVoid;
#endif
#ifndef UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_VOID
#define UNIFFI_FFIDEF_FOREIGN_FUTURE_COMPLETE_VOID
typedef void (*UniffiForeignFutureCompleteVoid)(uint64_t, UniffiForeignFutureStructVoid
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_SHARED_FN_FUNC_HANDLE_RESPONSE
#define UNIFFI_FFIDEF_UNIFFI_SHARED_FN_FUNC_HANDLE_RESPONSE
RustBuffer uniffi_shared_fn_func_handle_response(uint32_t id, RustBuffer res, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_SHARED_FN_FUNC_PROCESS_EVENT
#define UNIFFI_FFIDEF_UNIFFI_SHARED_FN_FUNC_PROCESS_EVENT
RustBuffer uniffi_shared_fn_func_process_event(RustBuffer msg, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_SHARED_FN_FUNC_VIEW
#define UNIFFI_FFIDEF_UNIFFI_SHARED_FN_FUNC_VIEW
RustBuffer uniffi_shared_fn_func_view(RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUSTBUFFER_ALLOC
#define UNIFFI_FFIDEF_FFI_SHARED_RUSTBUFFER_ALLOC
RustBuffer ffi_shared_rustbuffer_alloc(uint64_t size, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUSTBUFFER_FROM_BYTES
#define UNIFFI_FFIDEF_FFI_SHARED_RUSTBUFFER_FROM_BYTES
RustBuffer ffi_shared_rustbuffer_from_bytes(ForeignBytes bytes, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUSTBUFFER_FREE
#define UNIFFI_FFIDEF_FFI_SHARED_RUSTBUFFER_FREE
void ffi_shared_rustbuffer_free(RustBuffer buf, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUSTBUFFER_RESERVE
#define UNIFFI_FFIDEF_FFI_SHARED_RUSTBUFFER_RESERVE
RustBuffer ffi_shared_rustbuffer_reserve(RustBuffer buf, uint64_t additional, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_U8
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_U8
void ffi_shared_rust_future_poll_u8(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_U8
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_U8
void ffi_shared_rust_future_cancel_u8(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_U8
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_U8
void ffi_shared_rust_future_free_u8(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_U8
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_U8
uint8_t ffi_shared_rust_future_complete_u8(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_I8
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_I8
void ffi_shared_rust_future_poll_i8(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_I8
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_I8
void ffi_shared_rust_future_cancel_i8(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_I8
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_I8
void ffi_shared_rust_future_free_i8(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_I8
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_I8
int8_t ffi_shared_rust_future_complete_i8(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_U16
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_U16
void ffi_shared_rust_future_poll_u16(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_U16
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_U16
void ffi_shared_rust_future_cancel_u16(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_U16
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_U16
void ffi_shared_rust_future_free_u16(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_U16
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_U16
uint16_t ffi_shared_rust_future_complete_u16(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_I16
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_I16
void ffi_shared_rust_future_poll_i16(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_I16
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_I16
void ffi_shared_rust_future_cancel_i16(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_I16
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_I16
void ffi_shared_rust_future_free_i16(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_I16
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_I16
int16_t ffi_shared_rust_future_complete_i16(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_U32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_U32
void ffi_shared_rust_future_poll_u32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_U32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_U32
void ffi_shared_rust_future_cancel_u32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_U32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_U32
void ffi_shared_rust_future_free_u32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_U32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_U32
uint32_t ffi_shared_rust_future_complete_u32(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_I32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_I32
void ffi_shared_rust_future_poll_i32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_I32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_I32
void ffi_shared_rust_future_cancel_i32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_I32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_I32
void ffi_shared_rust_future_free_i32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_I32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_I32
int32_t ffi_shared_rust_future_complete_i32(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_U64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_U64
void ffi_shared_rust_future_poll_u64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_U64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_U64
void ffi_shared_rust_future_cancel_u64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_U64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_U64
void ffi_shared_rust_future_free_u64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_U64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_U64
uint64_t ffi_shared_rust_future_complete_u64(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_I64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_I64
void ffi_shared_rust_future_poll_i64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_I64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_I64
void ffi_shared_rust_future_cancel_i64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_I64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_I64
void ffi_shared_rust_future_free_i64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_I64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_I64
int64_t ffi_shared_rust_future_complete_i64(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_F32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_F32
void ffi_shared_rust_future_poll_f32(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_F32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_F32
void ffi_shared_rust_future_cancel_f32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_F32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_F32
void ffi_shared_rust_future_free_f32(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_F32
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_F32
float ffi_shared_rust_future_complete_f32(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_F64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_F64
void ffi_shared_rust_future_poll_f64(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_F64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_F64
void ffi_shared_rust_future_cancel_f64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_F64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_F64
void ffi_shared_rust_future_free_f64(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_F64
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_F64
double ffi_shared_rust_future_complete_f64(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_POINTER
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_POINTER
void ffi_shared_rust_future_poll_pointer(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_POINTER
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_POINTER
void ffi_shared_rust_future_cancel_pointer(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_POINTER
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_POINTER
void ffi_shared_rust_future_free_pointer(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_POINTER
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_POINTER
void*_Nonnull ffi_shared_rust_future_complete_pointer(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_RUST_BUFFER
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_RUST_BUFFER
void ffi_shared_rust_future_poll_rust_buffer(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_RUST_BUFFER
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_RUST_BUFFER
void ffi_shared_rust_future_cancel_rust_buffer(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_RUST_BUFFER
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_RUST_BUFFER
void ffi_shared_rust_future_free_rust_buffer(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_RUST_BUFFER
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_RUST_BUFFER
RustBuffer ffi_shared_rust_future_complete_rust_buffer(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_VOID
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_POLL_VOID
void ffi_shared_rust_future_poll_void(uint64_t handle, UniffiRustFutureContinuationCallback _Nonnull callback, uint64_t callback_data
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_VOID
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_CANCEL_VOID
void ffi_shared_rust_future_cancel_void(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_VOID
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_FREE_VOID
void ffi_shared_rust_future_free_void(uint64_t handle
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_VOID
#define UNIFFI_FFIDEF_FFI_SHARED_RUST_FUTURE_COMPLETE_VOID
void ffi_shared_rust_future_complete_void(uint64_t handle, RustCallStatus *_Nonnull out_status
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_SHARED_CHECKSUM_FUNC_HANDLE_RESPONSE
#define UNIFFI_FFIDEF_UNIFFI_SHARED_CHECKSUM_FUNC_HANDLE_RESPONSE
uint16_t uniffi_shared_checksum_func_handle_response(void
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_SHARED_CHECKSUM_FUNC_PROCESS_EVENT
#define UNIFFI_FFIDEF_UNIFFI_SHARED_CHECKSUM_FUNC_PROCESS_EVENT
uint16_t uniffi_shared_checksum_func_process_event(void
);
#endif
#ifndef UNIFFI_FFIDEF_UNIFFI_SHARED_CHECKSUM_FUNC_VIEW
#define UNIFFI_FFIDEF_UNIFFI_SHARED_CHECKSUM_FUNC_VIEW
uint16_t uniffi_shared_checksum_func_view(void
);
#endif
#ifndef UNIFFI_FFIDEF_FFI_SHARED_UNIFFI_CONTRACT_VERSION
#define UNIFFI_FFIDEF_FFI_SHARED_UNIFFI_CONTRACT_VERSION
uint32_t ffi_shared_uniffi_contract_version(void
);
#endif

View File

@ -0,0 +1,7 @@
module sharedFFI {
header "sharedFFI.h"
export *
use "Darwin"
use "_Builtin_stdbool"
use "_Builtin_stdint"
}

57
macOS/project.yml Normal file
View File

@ -0,0 +1,57 @@
name: AudioAlwaysWorks
projectReferences:
Shared:
path: ../shared/shared.xcodeproj
packages:
SharedTypes:
path: ../shared_types/generated/swift/SharedTypes
options:
bundleIdPrefix: nl.pascaldevink.audio_always_works
attributes:
BuildIndependentTargetsInParallel: true
targets:
AudioAlwaysWorks:
type: application
platform: macOS
deploymentTarget: "15.5"
sources:
- AudioAlwaysWorks
- path: ../shared/src/shared.udl
buildPhase: sources
dependencies:
- target: Shared/uniffi-bindgen-bin
- target: Shared/shared-staticlib
- package: SharedTypes
info:
path: AudioAlwaysWorks/Info.plist
properties:
UILaunchScreen: {}
settings:
OTHER_LDFLAGS: [-w]
SWIFT_OBJC_BRIDGING_HEADER: generated/sharedFFI.h
ENABLE_USER_SCRIPT_SANDBOXING: NO
buildRules:
- name: Generate FFI
filePattern: "*.udl"
script: |
#!/bin/bash
set -e
# Skip during indexing phase in XCode 13+
if [ "$ACTION" == "indexbuild" ]; then
echo "Not building *.udl files during indexing."
exit 0
fi
# Skip for preview builds
if [ "$ENABLE_PREVIEWS" = "YES" ]; then
echo "Not building *.udl files during preview builds."
exit 0
fi
cd "${INPUT_FILE_DIR}/.."
"${BUILD_DIR}/${CONFIGURATION}/uniffi-bindgen" generate "src/${INPUT_FILE_NAME}" --language swift --out-dir "${PROJECT_DIR}/generated"
outputFiles:
- $(PROJECT_DIR)/generated/$(INPUT_FILE_BASE).swift
- $(PROJECT_DIR)/generated/$(INPUT_FILE_BASE)FFI.h
runOncePerArchitecture: false

5
rust-toolchain.toml Normal file
View File

@ -0,0 +1,5 @@
[toolchain]
channel = "stable"
components = ["rustfmt", "rustc-dev"]
targets = ["aarch64-apple-darwin"]
profile = "minimal"

1
shared/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

27
shared/Cargo.toml Normal file
View File

@ -0,0 +1,27 @@
[package]
name = "shared"
version = "0.1.0"
authors.workspace = true
repository.workspace = true
edition.workspace = true
license.workspace = true
rust-version.workspace = true
[lib]
crate-type = ["lib", "staticlib", "cdylib"]
name = "shared"
[features]
typegen = ["crux_core/typegen"]
[dependencies]
crux_core.workspace = true
serde = { workspace = true, features = ["derive"] }
uniffi = "0.29.3"
wasm-bindgen = "0.2.100"
[build-dependencies]
uniffi = { version = "0.29.3", features = ["build"] }
[target.uniffi-bindgen.dependencies]
uniffi = { version = "0.29.3", features = ["cli"] }

3
shared/build.rs Normal file
View File

@ -0,0 +1,3 @@
fn main() {
uniffi::generate_scaffolding("./src/shared.udl").unwrap();
}

View File

@ -0,0 +1,391 @@
// !$*UTF8*$!
{
/* generated with cargo-xcode 1.7.0 */
archiveVersion = 1;
classes = {
};
objectVersion = 53;
objects = {
/* Begin PBXBuildFile section */
CA0075449799D346A0A05154 /* Cargo.toml in Sources */ = {isa = PBXBuildFile; fileRef = CAF972D1F1633EF4668187A5 /* Cargo.toml */; settings = {COMPILER_FLAGS = "--lib"; }; };
CA017544979925C0556334E4 /* Cargo.toml in Sources */ = {isa = PBXBuildFile; fileRef = CAF972D1F1633EF4668187A5 /* Cargo.toml */; settings = {COMPILER_FLAGS = "--lib"; }; };
CA02754497994296ADE0F606 /* Cargo.toml in Sources */ = {isa = PBXBuildFile; fileRef = CAF972D1F1633EF4668187A5 /* Cargo.toml */; settings = {COMPILER_FLAGS = "--bin 'uniffi-bindgen'"; }; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
CAF472D1F163AC6C1400ACA8 /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.apple.compilers.proxy.script;
dependencyFile = "$(DERIVED_FILE_DIR)/$(CARGO_XCODE_TARGET_ARCH)-$(EXECUTABLE_NAME).d";
filePatterns = "*/Cargo.toml";
fileType = pattern.proxy;
inputFiles = (
);
isEditable = 0;
name = "Cargo project build";
outputFiles = (
"$(OBJECT_FILE_DIR)/$(CARGO_XCODE_TARGET_ARCH)-$(EXECUTABLE_NAME)",
);
script = "# generated with cargo-xcode 1.7.0\nset -xeu;\nexport PATH=\"$HOME/.cargo/bin:$PATH:/usr/local/bin:/opt/homebrew/bin\";\n\nif [ \"${IS_MACCATALYST-NO}\" = YES ]; then\n CARGO_XCODE_TARGET_OS=ios-macabi\nfi\nCARGO_XCODE_TARGET_TRIPLE=\"${CARGO_XCODE_TARGET_ARCH}-apple-${CARGO_XCODE_TARGET_OS}\"\nif [ \"$CARGO_XCODE_TARGET_OS\" != darwin ]; then\n export PATH=\"${PATH/\\/Contents\\/Developer\\/Toolchains\\/XcodeDefault.xctoolchain\\/usr\\/bin:/xcode-provided-ld-cant-link-lSystem-for-the-host-build-script:}\"\nfi\nif [ \"$CARGO_XCODE_BUILD_PROFILE\" == release ]; then\n OTHER_INPUT_FILE_FLAGS=\"${OTHER_INPUT_FILE_FLAGS} --release\"\nfi\n\nif [ \"$ACTION\" = clean ]; then\n cargo clean --verbose --manifest-path=\"$SCRIPT_INPUT_FILE\" ${OTHER_INPUT_FILE_FLAGS} --target=\"${CARGO_XCODE_TARGET_TRIPLE}\";\n rm -f \"$SCRIPT_OUTPUT_FILE_0\"\n exit 0\nfi\ncargo build --verbose --manifest-path=\"$SCRIPT_INPUT_FILE\" --features=\"${CARGO_XCODE_FEATURES:-}\" ${OTHER_INPUT_FILE_FLAGS} --target=\"${CARGO_XCODE_TARGET_TRIPLE}\" || {\n if command -v rustup &> /dev/null; then\n if ! rustup target list --installed | grep -Eq \"${CARGO_XCODE_TARGET_TRIPLE}\"; then\n echo >&2 \"warning: this build requires rustup toolchain for $CARGO_XCODE_TARGET_TRIPLE, but it isn't installed (will try rustup next)\"\n rustup target add \"${CARGO_XCODE_TARGET_TRIPLE}\" || echo >&2 \"warning: can't install $CARGO_XCODE_TARGET_TRIPLE\"\n fi\n fi\n echo >&2 \"error: cargo build failed\"; exit 1; }\n\n# it's too hard to explain Cargo's actual exe path to Xcode build graph, so hardlink to a known-good path instead\nBUILT_SRC=\"${CARGO_TARGET_DIR}/${CARGO_XCODE_TARGET_TRIPLE}/${CARGO_XCODE_BUILD_PROFILE}/${CARGO_XCODE_CARGO_FILE_NAME}\"\nln -f -- \"$BUILT_SRC\" \"$SCRIPT_OUTPUT_FILE_0\" || { echo >&2 \"can't hardlink $BUILT_SRC to $SCRIPT_OUTPUT_FILE_0\"; exit 1; }\n\n# cargo generates a dep file, but for its own path, so append our rename to it\nDEP_FILE_SRC=\"${CARGO_TARGET_DIR}/${CARGO_XCODE_TARGET_TRIPLE}/${CARGO_XCODE_BUILD_PROFILE}/${CARGO_XCODE_CARGO_DEP_FILE_NAME}\"\nif [ -f \"$DEP_FILE_SRC\" ]; then\n DEP_FILE_DST=\"${DERIVED_FILE_DIR}/${CARGO_XCODE_TARGET_ARCH}-${EXECUTABLE_NAME}.d\"\n cp -f \"$DEP_FILE_SRC\" \"$DEP_FILE_DST\" || { echo >&2 \"can't copy $DEP_FILE_SRC to $DEP_FILE_DST\"; exit 1; }\n\n echo >> \"$DEP_FILE_DST\" \"${SCRIPT_OUTPUT_FILE_0/ /\\\\ /}: ${BUILT_SRC/ /\\\\ /}\"\nfi\n\n# lipo script needs to know all the platform-specific files that have been built\n# archs is in the file name, so that paths don't stay around after archs change\n# must match input for LipoScript\nFILE_LIST=\"${DERIVED_FILE_DIR}/${ARCHS}-${EXECUTABLE_NAME}.xcfilelist\"\ntouch \"$FILE_LIST\"\nif ! grep -Eq \"$SCRIPT_OUTPUT_FILE_0\" \"$FILE_LIST\" ; then\n echo >> \"$FILE_LIST\" \"$SCRIPT_OUTPUT_FILE_0\"\nfi\n\necho \"success: $ACTION of $SCRIPT_OUTPUT_FILE_0 for $CARGO_XCODE_TARGET_TRIPLE\"\n";
};
/* End PBXBuildRule section */
/* Begin PBXFileReference section */
CA0049BF7D4FFB09138082B7 /* libshared_static.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libshared_static.a; sourceTree = BUILT_PRODUCTS_DIR; };
CA01C51694BE10F7F7FCAC5B /* shared.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = shared.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
CA02FA85CE9E8109328FB0D5 /* uniffi-bindgen */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "uniffi-bindgen"; sourceTree = BUILT_PRODUCTS_DIR; };
CAF972D1F1633EF4668187A5 /* Cargo.toml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Cargo.toml; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
CAF072D1F163D65BC3C892A8 = {
isa = PBXGroup;
children = (
CAF972D1F1633EF4668187A5 /* Cargo.toml */,
CAF172D1F16322869D176AE5 /* Products */,
CAF272D1F16398AF0B5890DB /* Frameworks */,
);
sourceTree = "<group>";
};
CAF172D1F16322869D176AE5 /* Products */ = {
isa = PBXGroup;
children = (
CA0049BF7D4FFB09138082B7 /* libshared_static.a */,
CA01C51694BE10F7F7FCAC5B /* shared.dylib */,
CA02FA85CE9E8109328FB0D5 /* uniffi-bindgen */,
);
name = Products;
sourceTree = "<group>";
};
CAF272D1F16398AF0B5890DB /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
CA0049BF7D4FD346A0A05154 /* shared-staticlib */ = {
isa = PBXNativeTarget;
buildConfigurationList = CA009BFF234FD346A0A05154 /* Build configuration list for PBXNativeTarget "shared-staticlib" */;
buildPhases = (
CA002DB2DC98D346A0A05154 /* Sources */,
CAF572D1F163AF6EBB7F357C /* Universal Binary lipo */,
);
buildRules = (
CAF472D1F163AC6C1400ACA8 /* PBXBuildRule */,
);
dependencies = (
);
name = "shared-staticlib";
productName = libshared_static.a;
productReference = CA0049BF7D4FFB09138082B7 /* libshared_static.a */;
productType = "com.apple.product-type.library.static";
};
CA01C51694BE25C0556334E4 /* shared-cdylib */ = {
isa = PBXNativeTarget;
buildConfigurationList = CA019BFF234F25C0556334E4 /* Build configuration list for PBXNativeTarget "shared-cdylib" */;
buildPhases = (
CA012DB2DC9825C0556334E4 /* Sources */,
CAF572D1F163AF6EBB7F357C /* Universal Binary lipo */,
);
buildRules = (
CAF472D1F163AC6C1400ACA8 /* PBXBuildRule */,
);
dependencies = (
);
name = "shared-cdylib";
productName = shared.dylib;
productReference = CA01C51694BE10F7F7FCAC5B /* shared.dylib */;
productType = "com.apple.product-type.library.dynamic";
};
CA02FA85CE9E4296ADE0F606 /* uniffi-bindgen-bin */ = {
isa = PBXNativeTarget;
buildConfigurationList = CA029BFF234F4296ADE0F606 /* Build configuration list for PBXNativeTarget "uniffi-bindgen-bin" */;
buildPhases = (
CA022DB2DC984296ADE0F606 /* Sources */,
CAF572D1F163AF6EBB7F357C /* Universal Binary lipo */,
);
buildRules = (
CAF472D1F163AC6C1400ACA8 /* PBXBuildRule */,
);
dependencies = (
);
name = "uniffi-bindgen-bin";
productName = "uniffi-bindgen";
productReference = CA02FA85CE9E8109328FB0D5 /* uniffi-bindgen */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
CAF372D1F163E04653AD465F /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1500;
TargetAttributes = {
CA0049BF7D4FD346A0A05154 = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Automatic;
};
CA01C51694BE25C0556334E4 = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Automatic;
};
CA02FA85CE9E4296ADE0F606 = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = CAF672D1F16380E02D6C7F57 /* Build configuration list for PBXProject "shared" */;
compatibilityVersion = "Xcode 11.4";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = CAF072D1F163D65BC3C892A8;
productRefGroup = CAF172D1F16322869D176AE5 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
CA0049BF7D4FD346A0A05154 /* shared-staticlib */,
CA01C51694BE25C0556334E4 /* shared-cdylib */,
CA02FA85CE9E4296ADE0F606 /* uniffi-bindgen-bin */,
);
};
/* End PBXProject section */
/* Begin PBXShellScriptBuildPhase section */
CAF572D1F163AF6EBB7F357C /* Universal Binary lipo */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"$(DERIVED_FILE_DIR)/$(ARCHS)-$(EXECUTABLE_NAME).xcfilelist",
);
name = "Universal Binary lipo";
outputFileListPaths = (
);
outputPaths = (
"$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# generated with cargo-xcode 1.7.0\nset -eux;\ntr '\\n' '\\0' < \"$DERIVED_FILE_DIR/$ARCHS-$EXECUTABLE_NAME.xcfilelist\" | xargs -0 lipo -create -output \"$TARGET_BUILD_DIR/$EXECUTABLE_PATH\"\nif [ ${LD_DYLIB_INSTALL_NAME:+1} ]; then\n install_name_tool -id \"$LD_DYLIB_INSTALL_NAME\" \"$TARGET_BUILD_DIR/$EXECUTABLE_PATH\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
CA002DB2DC98D346A0A05154 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CA0075449799D346A0A05154 /* Cargo.toml in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CA012DB2DC9825C0556334E4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CA017544979925C0556334E4 /* Cargo.toml in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CA022DB2DC984296ADE0F606 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CA02754497994296ADE0F606 /* Cargo.toml in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
CA00D94DC8EDD346A0A05154 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CARGO_XCODE_CARGO_DEP_FILE_NAME = libshared.d;
CARGO_XCODE_CARGO_FILE_NAME = libshared.a;
INSTALL_GROUP = "";
INSTALL_MODE_FLAG = "";
INSTALL_OWNER = "";
SKIP_INSTALL = YES;
PRODUCT_NAME = shared_static;
SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos appletvsimulator appletvos";
};
name = Release;
};
CA00F2363223D346A0A05154 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CARGO_XCODE_CARGO_DEP_FILE_NAME = libshared.d;
CARGO_XCODE_CARGO_FILE_NAME = libshared.a;
INSTALL_GROUP = "";
INSTALL_MODE_FLAG = "";
INSTALL_OWNER = "";
SKIP_INSTALL = YES;
PRODUCT_NAME = shared_static;
SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos appletvsimulator appletvos";
};
name = Debug;
};
CA01D94DC8ED25C0556334E4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CARGO_XCODE_CARGO_DEP_FILE_NAME = libshared.d;
CARGO_XCODE_CARGO_FILE_NAME = libshared.dylib;
PRODUCT_NAME = shared;
SUPPORTED_PLATFORMS = macosx;
DYLIB_COMPATIBILITY_VERSION = 0;
};
name = Release;
};
CA01F236322325C0556334E4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CARGO_XCODE_CARGO_DEP_FILE_NAME = libshared.d;
CARGO_XCODE_CARGO_FILE_NAME = libshared.dylib;
PRODUCT_NAME = shared;
SUPPORTED_PLATFORMS = macosx;
DYLIB_COMPATIBILITY_VERSION = 0;
};
name = Debug;
};
CA02D94DC8ED4296ADE0F606 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CARGO_XCODE_CARGO_DEP_FILE_NAME = "uniffi-bindgen.d";
CARGO_XCODE_CARGO_FILE_NAME = "uniffi-bindgen";
PRODUCT_NAME = "uniffi-bindgen";
SUPPORTED_PLATFORMS = macosx;
};
name = Release;
};
CA02F23632234296ADE0F606 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CARGO_XCODE_CARGO_DEP_FILE_NAME = "uniffi-bindgen.d";
CARGO_XCODE_CARGO_FILE_NAME = "uniffi-bindgen";
PRODUCT_NAME = "uniffi-bindgen";
SUPPORTED_PLATFORMS = macosx;
};
name = Debug;
};
CAF73C790FAA3CC16B37690B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CARGO_TARGET_DIR = "$(PROJECT_TEMP_DIR)/cargo_target";
CARGO_XCODE_BUILD_PROFILE = release;
CARGO_XCODE_FEATURES = "";
"CARGO_XCODE_TARGET_ARCH[arch=arm64*]" = aarch64;
"CARGO_XCODE_TARGET_ARCH[arch=i386]" = i686;
"CARGO_XCODE_TARGET_ARCH[arch=x86_64*]" = x86_64;
"CARGO_XCODE_TARGET_OS[sdk=appletvos*]" = tvos;
"CARGO_XCODE_TARGET_OS[sdk=appletvsimulator*]" = tvos;
"CARGO_XCODE_TARGET_OS[sdk=iphoneos*]" = ios;
"CARGO_XCODE_TARGET_OS[sdk=iphonesimulator*]" = "ios-sim";
"CARGO_XCODE_TARGET_OS[sdk=iphonesimulator*][arch=x86_64*]" = ios;
"CARGO_XCODE_TARGET_OS[sdk=macosx*]" = darwin;
CURRENT_PROJECT_VERSION = 0.1;
MARKETING_VERSION = 0.1.0;
PRODUCT_NAME = shared;
RUSTUP_TOOLCHAIN = "";
SDKROOT = macosx;
SUPPORTS_MACCATALYST = YES;
};
name = Release;
};
CAF83C790FAA228BE02872F8 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CARGO_TARGET_DIR = "$(PROJECT_TEMP_DIR)/cargo_target";
CARGO_XCODE_BUILD_PROFILE = debug;
CARGO_XCODE_FEATURES = "";
"CARGO_XCODE_TARGET_ARCH[arch=arm64*]" = aarch64;
"CARGO_XCODE_TARGET_ARCH[arch=i386]" = i686;
"CARGO_XCODE_TARGET_ARCH[arch=x86_64*]" = x86_64;
"CARGO_XCODE_TARGET_OS[sdk=appletvos*]" = tvos;
"CARGO_XCODE_TARGET_OS[sdk=appletvsimulator*]" = tvos;
"CARGO_XCODE_TARGET_OS[sdk=iphoneos*]" = ios;
"CARGO_XCODE_TARGET_OS[sdk=iphonesimulator*]" = "ios-sim";
"CARGO_XCODE_TARGET_OS[sdk=iphonesimulator*][arch=x86_64*]" = ios;
"CARGO_XCODE_TARGET_OS[sdk=macosx*]" = darwin;
CURRENT_PROJECT_VERSION = 0.1;
MARKETING_VERSION = 0.1.0;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = shared;
RUSTUP_TOOLCHAIN = "";
SDKROOT = macosx;
SUPPORTS_MACCATALYST = YES;
};
name = Debug;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
CA009BFF234FD346A0A05154 /* Build configuration list for PBXNativeTarget "shared-staticlib" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CA00D94DC8EDD346A0A05154 /* Release */,
CA00F2363223D346A0A05154 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CA019BFF234F25C0556334E4 /* Build configuration list for PBXNativeTarget "shared-cdylib" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CA01D94DC8ED25C0556334E4 /* Release */,
CA01F236322325C0556334E4 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CA029BFF234F4296ADE0F606 /* Build configuration list for PBXNativeTarget "uniffi-bindgen-bin" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CA02D94DC8ED4296ADE0F606 /* Release */,
CA02F23632234296ADE0F606 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CAF672D1F16380E02D6C7F57 /* Build configuration list for PBXProject "shared" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CAF73C790FAA3CC16B37690B /* Release */,
CAF83C790FAA228BE02872F8 /* Debug */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = CAF372D1F163E04653AD465F /* Project object */;
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>shared-cdylib.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>shared-staticlib.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
<key>uniffi-bindgen-bin.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
</dict>
</dict>
</dict>
</plist>

76
shared/src/app.rs Normal file
View File

@ -0,0 +1,76 @@
use crux_core::{
macros::effect,
render::{render, RenderOperation},
App, Command,
};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum Event {
AudioDevicesChanged,
DefaultInputDeviceChanged(String),
DefaultOutputDeviceChanged(String),
}
#[effect(typegen)]
pub enum Effect {
Render(RenderOperation),
}
#[derive(Default)]
pub struct Model {
input_devices: Vec<String>,
output_devices: Vec<String>,
selected_input_device: String,
selected_output_device: String,
rules: Vec<String>,
}
#[derive(Serialize, Deserialize, Clone, Default)]
pub struct ViewModel {
pub input_devices: Vec<String>,
pub output_devices: Vec<String>,
pub selected_input_device: String,
pub selected_output_device: String,
pub rules: Vec<String>,
}
#[derive(Default)]
pub struct AudioAlwaysWorks;
impl App for AudioAlwaysWorks {
type Event = Event;
type Model = Model;
type ViewModel = ViewModel;
type Capabilities = (); // will be deprecated, so use unit type for now
type Effect = Effect;
fn update(
&self,
event: Self::Event,
model: &mut Self::Model,
_caps: &(), // will be deprecated, so prefix with underscore for now
) -> Command<Effect, Event> {
match event {
Event::DefaultInputDeviceChanged(device) => {
model.selected_input_device = device;
}
Event::DefaultOutputDeviceChanged(device) => {
model.selected_output_device = device;
}
_ => {}
}
render()
}
fn view(&self, model: &Self::Model) -> Self::ViewModel {
ViewModel {
input_devices: model.input_devices.clone(),
output_devices: model.output_devices.clone(),
selected_input_device: model.selected_input_device.clone(),
selected_output_device: model.selected_output_device.clone(),
rules: model.rules.clone(),
}
}
}

View File

@ -0,0 +1,3 @@
fn main() {
uniffi::uniffi_bindgen_main();
}

50
shared/src/lib.rs Normal file
View File

@ -0,0 +1,50 @@
pub mod app;
use std::sync::LazyLock;
pub use crux_core::{bridge::Bridge, Core, Request};
pub use app::*;
// TODO hide this plumbing
#[cfg(not(target_family = "wasm"))]
uniffi::include_scaffolding!("shared");
static CORE: LazyLock<Bridge<AudioAlwaysWorks>> = LazyLock::new(|| Bridge::new(Core::new()));
/// Ask the core to process an event
/// # Panics
/// If the core fails to process the event
#[cfg_attr(target_family = "wasm", wasm_bindgen::prelude::wasm_bindgen)]
#[must_use]
pub fn process_event(data: &[u8]) -> Vec<u8> {
match CORE.process_event(data) {
Ok(effects) => effects,
Err(e) => panic!("{e}"),
}
}
/// Ask the core to handle a response
/// # Panics
/// If the core fails to handle the response
#[cfg_attr(target_family = "wasm", wasm_bindgen::prelude::wasm_bindgen)]
#[must_use]
pub fn handle_response(id: u32, data: &[u8]) -> Vec<u8> {
match CORE.handle_response(id, data) {
Ok(effects) => effects,
Err(e) => panic!("{e}"),
}
}
/// Ask the core to render the view
/// # Panics
/// If the view cannot be serialized
#[cfg_attr(target_family = "wasm", wasm_bindgen::prelude::wasm_bindgen)]
#[must_use]
pub fn view() -> Vec<u8> {
match CORE.view() {
Ok(view) => view,
Err(e) => panic!("{e}"),
}
}

5
shared/src/shared.udl Normal file
View File

@ -0,0 +1,5 @@
namespace shared {
bytes process_event([ByRef] bytes msg);
bytes handle_response(u32 id, [ByRef] bytes res);
bytes view();
};

7
shared/uniffi.toml Normal file
View File

@ -0,0 +1,7 @@
[bindings.kotlin]
package_name = "nl.pascaldevink.audio_always_works.shared"
cdylib_name = "shared"
[bindings.swift]
cdylib_name = "shared_ffi"
omit_argument_labels = true

1
shared_types/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

14
shared_types/Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "shared_types"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
rust-version.workspace = true
[dependencies]
[build-dependencies]
anyhow.workspace = true
crux_core = { workspace = true, features = ["typegen"] }
shared = { path = "../shared", features = ["typegen"] }

23
shared_types/build.rs Normal file
View File

@ -0,0 +1,23 @@
use crux_core::typegen::TypeGen;
use shared::AudioAlwaysWorks;
use std::path::PathBuf;
fn main() -> anyhow::Result<()> {
println!("cargo:rerun-if-changed=../shared");
let mut typegen = TypeGen::new();
typegen.register_app::<AudioAlwaysWorks>()?;
let output_root = PathBuf::from("./generated");
typegen.swift("SharedTypes", output_root.join("swift"))?;
// For Android
// typegen.java("com.crux.example.simple_counter", output_root.join("java"))?;
// For web-shell
// typegen.typescript("shared_types", output_root.join("typescript"))?;
Ok(())
}

1
shared_types/src/lib.rs Normal file
View File

@ -0,0 +1 @@
// see build.rs