Skip to content

Commit ef65bb7

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

File tree

2 files changed

+176
-2
lines changed

2 files changed

+176
-2
lines changed

gio/src/file.rs

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

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)