Skip to content

Commit 6b9d93b

Browse files
authored
cosmos: add experimental c wrapper around cosmos sdk
1 parent 5c708e3 commit 6b9d93b

File tree

10 files changed

+151
-1
lines changed

10 files changed

+151
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ members = [
2121
"sdk/template/azure_template_core",
2222
"sdk/template/azure_template",
2323
"sdk/storage/azure_storage_common",
24-
"sdk/storage/azure_storage_blob",
24+
"sdk/storage/azure_storage_blob", "sdk/cosmos/cosmosclient",
2525
]
2626
exclude = [
2727
"eng/scripts",

sdk/cosmos/azure_data_cosmos/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ workspace = true
3737

3838
[features]
3939
default = ["hmac_rust"]
40+
_internal_c = [] # Internal feature used to expose additional types/functions as needed to build libcosmosclient.
4041
key_auth = [] # Enables support for key-based authentication (Primary Keys and Resource Tokens)
4142
preview_query_engine = ["serde_json/raw_value"] # Enables support for the PREVIEW external query engine
4243
hmac_rust = ["azure_core/hmac_rust"]

sdk/cosmos/cosmosclient/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
project(cosmosctest C)
2+
cmake_minimum_required(VERSION 4.1)
3+
4+
# CMake automatically uses this option, but we should define it.
5+
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
6+
7+
include(FetchContent)
8+
include(CTest)
9+
10+
FetchContent_Declare(
11+
Corrosion
12+
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
13+
GIT_TAG v0.5.2
14+
)
15+
FetchContent_MakeAvailable(Corrosion)
16+
17+
corrosion_import_crate(
18+
MANIFEST_PATH ./Cargo.toml
19+
CRATETYPES staticlib cdylib
20+
)
21+
22+
set(TEST_FILES
23+
./c_tests/version.c)
24+
25+
foreach(test_file ${TEST_FILES})
26+
get_filename_component(test_name ${test_file} NAME_WE)
27+
add_executable(${test_name} ${test_file})
28+
target_link_libraries(${test_name} PRIVATE cosmosclient)
29+
add_test(${test_name} ${test_name})
30+
endforeach()
31+

sdk/cosmos/cosmosclient/Cargo.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "cosmosclient"
3+
description = "C library wrapping the Azure CosmosDB SDK for Rust"
4+
version = "0.27.0"
5+
authors.workspace = true
6+
edition.workspace = true
7+
license.workspace = true
8+
repository.workspace = true
9+
rust-version.workspace = true
10+
11+
[lib]
12+
crate-type = ["cdylib", "staticlib"]
13+
14+
[dependencies]
15+
azure_data_cosmos = { path = "../azure_data_cosmos", features = ["_internal_c"] }
16+
17+
[build-dependencies]
18+
cbindgen = "0.29.0"
19+
20+
[lints]
21+
workspace = true

sdk/cosmos/cosmosclient/build.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
fn main() {
2+
let build_id = format!(
3+
"$Id: {}, Version: {}, Commit: {}, Branch: {}, Build ID: {}, Build Number: {}, Timestamp: {}$",
4+
env!("CARGO_PKG_NAME"),
5+
env!("CARGO_PKG_VERSION"),
6+
option_env!("BUILD_SOURCEVERSION").unwrap_or("unknown"),
7+
option_env!("BUILD_SOURCEBRANCH").unwrap_or("unknown"),
8+
option_env!("BUILD_BUILDID").unwrap_or("unknown"),
9+
option_env!("BUILD_BUILDNUMBER").unwrap_or("unknown"),
10+
std::time::SystemTime::now()
11+
.duration_since(std::time::UNIX_EPOCH)
12+
.unwrap_or_default()
13+
.as_secs(),
14+
);
15+
println!("cargo:rustc-env=BUILD_IDENTIFIER={}", build_id);
16+
17+
let mut header: String = r"// Copyright (c) Microsoft Corporation. All rights reserved.
18+
// Licensed under the MIT License.
19+
20+
// This file is auto-generated by cbindgen. Do not edit manually.
21+
"
22+
.to_string();
23+
header.push_str(&format!("// Build identifier: {}\n", build_id));
24+
25+
let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
26+
cbindgen::Builder::new()
27+
.with_crate(crate_dir)
28+
.with_language(cbindgen::Language::C)
29+
.with_after_include(format!(
30+
"\n// Specifies the version of cosmosclient this header file was generated from.\n// This should match the version of libcosmosclient you are referencing.\n#define COSMOSCLIENT_H_VERSION \"{}\"",
31+
env!("CARGO_PKG_VERSION")
32+
))
33+
.with_cpp_compat(true)
34+
.with_header(header)
35+
.generate()
36+
.expect("unable to generate bindings")
37+
.write_to_file("include/cosmosclient.h");
38+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Cosmos Client C Tests
2+
3+
This directory contains tests written in C that utilize the Cosmos Client library. The tests are designed to validate the functionality of the Cosmos Client C API, ensuring that it correctly interacts with the Azure CosmosDB service.
4+
5+
Building this directory requires CMake, Rust, and a C compiler.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include "../include/cosmosclient.h"
4+
5+
int main() {
6+
const char *version = cosmosclient_version();
7+
const char *header_version = COSMOSCLIENT_H_VERSION;
8+
printf("Cosmos Client Version: %s\n", version);
9+
printf("Header Version: %s\n", header_version);
10+
if (!strcmp(version, header_version)) {
11+
printf("Version match successful.\n");
12+
return 0;
13+
} else {
14+
printf("Version mismatch: %s != %s\n", version, header_version);
15+
return 1;
16+
}
17+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Ignore everything except this ignore file, this directory contains build artifacts
2+
*
3+
!.gitignore

sdk/cosmos/cosmosclient/src/lib.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use std::ffi::{c_char, CStr, CString};
2+
3+
#[no_mangle] // Necessary to prevent the compiler from stripping it when optimizing
4+
/// cbindgen:ignore
5+
pub static BUILD_IDENTIFIER: &CStr = const {
6+
// This does a few funky things to make sure we can stay in a const context
7+
// Which ensures the string is generated as a c-str at compile time
8+
// and thus appears properly if you run `strings [lib] | grep "\$Id:"`
9+
const BUILD_IDENTIFIER_STR: &str = env!("BUILD_IDENTIFIER");
10+
const BUILD_IDENTIFIER_BYTES: [u8; BUILD_IDENTIFIER_STR.len() + 1] = const {
11+
let mut cstrbuf: [u8; BUILD_IDENTIFIER_STR.len() + 1] = [0; BUILD_IDENTIFIER_STR.len() + 1];
12+
let mut i = 0;
13+
// For loops over ranges don't really work in const contexts.
14+
while i < BUILD_IDENTIFIER_STR.len() {
15+
cstrbuf[i] = BUILD_IDENTIFIER_STR.as_bytes()[i];
16+
i += 1;
17+
}
18+
cstrbuf
19+
};
20+
match CStr::from_bytes_with_nul(&BUILD_IDENTIFIER_BYTES) {
21+
Ok(cstr) => cstr,
22+
Err(_) => panic!("BUILD_IDENTIFIER is not a valid C string"),
23+
}
24+
};
25+
26+
#[no_mangle]
27+
/// Returns a constant C string containing the version of the Cosmos Client library.
28+
pub extern "C" fn cosmosclient_version() -> *const c_char {
29+
let version = env!("CARGO_PKG_VERSION");
30+
CString::new(version)
31+
.expect("failed to create CString from version")
32+
.into_raw()
33+
}

0 commit comments

Comments
 (0)