Skip to content

Commit e53d619

Browse files
committed
Implement gio::File::set_attribute
Signed-off-by: fbrouille <[email protected]>
1 parent 39e634f commit e53d619

File tree

2 files changed

+170
-2
lines changed

2 files changed

+170
-2
lines changed

gio/src/file.rs

Lines changed: 169 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
// Take a look at the license at the top of the repository in the LICENSE file.
22

3-
use std::{cell::RefCell, mem, pin::Pin, ptr};
3+
use std::{cell::RefCell, ffi::CStr, mem, pin::Pin, ptr};
44

55
use glib::{prelude::*, translate::*};
66

77
#[cfg(feature = "v2_74")]
88
use crate::FileIOStream;
9-
use crate::{ffi, Cancellable, File, FileCreateFlags, FileEnumerator, FileQueryInfoFlags};
9+
use crate::{
10+
ffi, Cancellable, File, FileAttributeType, FileCreateFlags, FileEnumerator, FileQueryInfoFlags,
11+
};
1012

1113
impl File {
1214
#[cfg(feature = "v2_74")]
@@ -1111,6 +1113,171 @@ pub trait FileExtManual: IsA<File> + Sized {
11111113

11121114
(fut, Box::pin(receiver))
11131115
}
1116+
1117+
#[doc(alias = "g_file_set_attribute")]
1118+
fn set_attribute(
1119+
&self,
1120+
attribute: &str,
1121+
type_value: FileAttributeTypeValue,
1122+
flags: FileQueryInfoFlags,
1123+
cancellable: Option<&impl IsA<Cancellable>>,
1124+
) -> Result<(), glib::Error> {
1125+
unsafe {
1126+
let mut error = std::ptr::null_mut();
1127+
let is_ok = ffi::g_file_set_attribute(
1128+
self.as_ref().to_glib_none().0,
1129+
attribute.to_glib_none().0,
1130+
type_value.as_ref().type_().into_glib(),
1131+
type_value.as_ref().value().as_ptr(),
1132+
flags.into_glib(),
1133+
cancellable.map(|p| p.as_ref()).to_glib_none().0,
1134+
&mut error,
1135+
);
1136+
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1137+
if error.is_null() {
1138+
Ok(())
1139+
} else {
1140+
Err(from_glib_full(error))
1141+
}
1142+
}
1143+
}
11141144
}
11151145

11161146
impl<O: IsA<File>> FileExtManual for O {}
1147+
1148+
#[derive(Debug)]
1149+
pub struct FileAttributeTypeValue<'a>(FileAttributeTypeValueInner<'a>);
1150+
1151+
impl<'a> FileAttributeTypeValue<'a> {
1152+
pub fn new_string(value: &'a str) -> Self {
1153+
Self(FileAttributeTypeValueInner::String(value))
1154+
}
1155+
1156+
pub fn new_byte_string(value: &'a CStr) -> Self {
1157+
Self(FileAttributeTypeValueInner::ByteString(value))
1158+
}
1159+
1160+
pub fn new_boolean(value: bool) -> Self {
1161+
Self(FileAttributeTypeValueInner::Boolean(value))
1162+
}
1163+
1164+
pub fn new_uint32(value: u32) -> Self {
1165+
Self(FileAttributeTypeValueInner::Uint32(value))
1166+
}
1167+
1168+
pub fn new_int32(value: i32) -> Self {
1169+
Self(FileAttributeTypeValueInner::Int32(value))
1170+
}
1171+
1172+
pub fn new_uint64(value: u64) -> Self {
1173+
Self(FileAttributeTypeValueInner::Uint64(value))
1174+
}
1175+
1176+
pub fn new_int64(value: i64) -> Self {
1177+
Self(FileAttributeTypeValueInner::Int64(value))
1178+
}
1179+
1180+
pub fn new_object<T: AsRef<glib::Object>>(value: &'a T) -> Self {
1181+
Self(FileAttributeTypeValueInner::Object(value.as_ref()))
1182+
}
1183+
1184+
pub fn new_stringv(value: &'a Vec<&'a str>) -> Self {
1185+
Self(FileAttributeTypeValueInner::Stringv(value))
1186+
}
1187+
}
1188+
1189+
impl<'a> AsRef<FileAttributeTypeValueInner<'a>> for FileAttributeTypeValue<'a> {
1190+
fn as_ref(&self) -> &FileAttributeTypeValueInner<'a> {
1191+
&self.0
1192+
}
1193+
}
1194+
1195+
#[derive(Debug)]
1196+
pub(crate) enum FileAttributeTypeValueInner<'a> {
1197+
#[allow(dead_code)] // TODO remove this allow attribute when Pointer will be used by this crate
1198+
Pointer(FileAttributeType, glib::ffi::gpointer),
1199+
String(&'a str),
1200+
ByteString(&'a CStr),
1201+
Boolean(bool),
1202+
Uint32(u32),
1203+
Int32(i32),
1204+
Uint64(u64),
1205+
Int64(i64),
1206+
Object(&'a glib::Object),
1207+
Stringv(&'a Vec<&'a str>),
1208+
}
1209+
1210+
impl<'a> FileAttributeTypeValueInner<'a> {
1211+
pub(crate) fn type_(&self) -> FileAttributeType {
1212+
match self {
1213+
Self::Pointer(type_, _) => *type_,
1214+
Self::String(_) => FileAttributeType::String,
1215+
Self::ByteString(_) => FileAttributeType::ByteString,
1216+
Self::Boolean(_) => FileAttributeType::Boolean,
1217+
Self::Uint32(_) => FileAttributeType::Uint32,
1218+
Self::Int32(_) => FileAttributeType::Int32,
1219+
Self::Uint64(_) => FileAttributeType::Uint64,
1220+
Self::Int64(_) => FileAttributeType::Int64,
1221+
Self::Object(_) => FileAttributeType::Object,
1222+
Self::Stringv(_) => FileAttributeType::Stringv,
1223+
}
1224+
}
1225+
1226+
pub(crate) fn value(&self) -> FileAttributeTypeValueStorage<'a> {
1227+
match self {
1228+
Self::Pointer(_, pointer) => FileAttributeTypeValueStorage::Pointer(*pointer),
1229+
Self::String(value) => FileAttributeTypeValueStorage::String(
1230+
ToGlibPtr::<*mut libc::c_char>::to_glib_none(value).1,
1231+
),
1232+
Self::ByteString(value) => {
1233+
FileAttributeTypeValueStorage::ByteString(
1234+
ToGlibPtr::<*mut libc::c_char>::to_glib_none(value),
1235+
)
1236+
}
1237+
Self::Boolean(value) => FileAttributeTypeValueStorage::Boolean(value.into_glib()),
1238+
Self::Uint32(value) => FileAttributeTypeValueStorage::Uint32(*value),
1239+
Self::Int32(value) => FileAttributeTypeValueStorage::Int32(*value),
1240+
Self::Uint64(value) => FileAttributeTypeValueStorage::Uint64(*value),
1241+
Self::Int64(value) => FileAttributeTypeValueStorage::Int64(*value),
1242+
Self::Object(value) => {
1243+
FileAttributeTypeValueStorage::Object(ToGlibPtr::<
1244+
<glib::Object as glib::translate::GlibPtrDefault>::GlibType,
1245+
>::to_glib_none(value))
1246+
}
1247+
Self::Stringv(value) => FileAttributeTypeValueStorage::Stringv(
1248+
ToGlibContainerFromSlice::<*mut *mut libc::c_char>::to_glib_none_from_slice(value)
1249+
.1,
1250+
),
1251+
}
1252+
}
1253+
}
1254+
1255+
pub(crate) enum FileAttributeTypeValueStorage<'a> {
1256+
Pointer(glib::ffi::gpointer),
1257+
String(<&'a str as ToGlibPtr<'a, *mut libc::c_char>>::Storage),
1258+
ByteString(Stash<'a, *mut libc::c_char, CStr>),
1259+
Boolean(glib::ffi::gboolean),
1260+
Uint32(u32),
1261+
Int32(i32),
1262+
Uint64(u64),
1263+
Int64(i64),
1264+
Object(Stash<'a, <glib::Object as glib::translate::GlibPtrDefault>::GlibType, glib::Object>),
1265+
Stringv(<&'a str as ToGlibContainerFromSlice<'a, *mut *mut libc::c_char>>::Storage),
1266+
}
1267+
1268+
impl FileAttributeTypeValueStorage<'_> {
1269+
pub(crate) fn as_ptr(&self) -> glib::ffi::gpointer {
1270+
match self {
1271+
Self::Pointer(s) => *s,
1272+
Self::String(s) => s.as_ptr() as _,
1273+
Self::ByteString(s) => s.0 as _,
1274+
Self::Boolean(s) => s as *const i32 as _,
1275+
Self::Uint32(s) => s as *const u32 as _,
1276+
Self::Int32(s) => s as *const i32 as _,
1277+
Self::Uint64(s) => s as *const u64 as _,
1278+
Self::Int64(s) => s as *const i64 as _,
1279+
Self::Object(s) => s.0 as _,
1280+
Self::Stringv(s) => s.1.as_ref().unwrap().as_ptr() as _,
1281+
}
1282+
}
1283+
}

gio/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ mod debug_controller_dbus;
4343
mod desktop_app_info;
4444
mod error;
4545
mod file;
46+
pub use file::FileAttributeTypeValue;
4647
mod file_attribute_info;
4748
pub use crate::file_attribute_info::FileAttributeInfo;
4849
mod file_attribute_info_list;

0 commit comments

Comments
 (0)