1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
//------------------------------------------------------------------------------
// Luke Titley : from+usd_rs@luketitley.com
//------------------------------------------------------------------------------
use crate::pxr;
use cpp::*;
use std::ffi::CStr;
cpp! {{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#include "pxr/usd/sdf/assetPath.h"
#pragma GCC diagnostic pop
}}
//------------------------------------------------------------------------------
/// This is a reference to an AssetPath.
///
/// &AssetPathRef is to [AssetPath], as &str is to String.
///
#[repr(C, align(8))]
pub struct AssetPathRef {
// A private member stops users from being able to construct it without
// Schema get_instance
_priv: u8,
}
//------------------------------------------------------------------------------
impl AssetPathRef {
/// Return the asset path as a &str
pub fn get_asset_path(&self) -> pxr::Result<&str> {
use std::os::raw::c_char;
let result = unsafe {
CStr::from_ptr(
cpp!([self as "const pxr::SdfAssetPath*"] -> * const c_char as "const char *" {
return self->GetAssetPath().c_str();
}),
)
};
Ok(result.to_str()?)
}
/// Return the resolved asset path(as a &str) if any.
///
/// Note that [AssetPath] carries a resolved path only if its creator
/// passed one to the constructor. [AssetPath] never performs resolution
/// itself.
pub fn get_resolved_path(&self) -> pxr::Result<&str> {
use std::os::raw::c_char;
let result = unsafe {
CStr::from_ptr(
cpp!([self as "const pxr::SdfAssetPath*"] -> * const c_char as "const char *" {
return self->GetResolvedPath().c_str();
}),
)
};
Ok(result.to_str()?)
}
}
impl std::fmt::Display for AssetPathRef {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Ok(text) = self.get_asset_path() {
write!(f, "{}", text)
} else {
write!(f, "<invalid path>")
}
}
}
//------------------------------------------------------------------------------
// AssetPathDescriptor
//------------------------------------------------------------------------------
pub struct AssetPathDescriptor<'a> {
/// The path to hold
pub path: &'a str,
/// The resolved path, this is optional
pub resolved_path: Option<&'a str>,
}
//------------------------------------------------------------------------------
/// Contains an asset path and an optional resolved path. Asset paths may
/// contain non-control UTF-8 encoded characters. Specifically, U+0000..U+001F
/// (C0 controls), U+007F (delete), and U+0080..U+009F (C1 controls) are
/// disallowed. Attempts to construct asset paths with such characters will
/// issue a TfError and produce the default-constructed empty asset path.
#[repr(C, align(8))]
pub struct AssetPath {
_asset_path: *const AssetPathRef,
}
//------------------------------------------------------------------------------
impl AssetPath {
/// Construct an asset path with `path` and an associated `resolvedPath`.
///
/// If either the passed `path` or `resolvedPath` are not valid UTF-8 or
/// either contain C0 or C1 control characters, raise a TfError and return
/// the default-constructed empty asset path.
///
/// The parameters are in [AssetPathDescriptor].
pub fn new(desc: AssetPathDescriptor) -> pxr::Result<Self> {
Ok(match desc {
AssetPathDescriptor {
path,
resolved_path: Some(resolved_path),
} => unsafe {
let path = std::ffi::CString::new(path)?;
let resolved_path = std::ffi::CString::new(resolved_path)?;
let path_c_char = path.as_ptr() as *const std::os::raw::c_char;
let resolved_path_c_char =
resolved_path.as_ptr() as *const std::os::raw::c_char;
cpp!([path_c_char as "const char *", resolved_path_c_char as "const char *"]
-> AssetPath as "const pxr::SdfAssetPath*" {
return new pxr::SdfAssetPath(std::string(path_c_char), std::string(resolved_path_c_char));
})
},
AssetPathDescriptor { path, .. } => unsafe {
let path = std::ffi::CString::new(path)?;
let path_c_char = path.as_ptr() as *const std::os::raw::c_char;
cpp!([path_c_char as "const char *"]
-> AssetPath as "const pxr::SdfAssetPath*" {
return new pxr::SdfAssetPath(std::string(path_c_char));
})
},
})
}
}
//------------------------------------------------------------------------------
impl Drop for AssetPath {
fn drop(&mut self) {
let asset_path = self._asset_path.clone();
unsafe {
cpp!([asset_path as "const pxr::SdfAssetPath*"] {
delete asset_path;
})
}
}
}
//------------------------------------------------------------------------------
impl AsRef<AssetPathRef> for AssetPath {
fn as_ref(&self) -> &AssetPathRef {
unsafe { &*(self._asset_path) }
}
}
//------------------------------------------------------------------------------
impl std::ops::Deref for AssetPath {
type Target = AssetPathRef;
fn deref(&self) -> &Self::Target {
self.as_ref()
}
}