Skip to content

Commit 7520fd3

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

File tree

2 files changed

+150
-2
lines changed

2 files changed

+150
-2
lines changed

gio/src/file.rs

Lines changed: 149 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,151 @@ 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<'a>(
1119+
&self,
1120+
attribute: &str,
1121+
value: impl Into<FileAttributeValue<'a>>,
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 value: FileAttributeValue<'a> = value.into();
1128+
let is_ok = ffi::g_file_set_attribute(
1129+
self.as_ref().to_glib_none().0,
1130+
attribute.to_glib_none().0,
1131+
value.type_().into_glib(),
1132+
value.as_ptr(),
1133+
flags.into_glib(),
1134+
cancellable.map(|p| p.as_ref()).to_glib_none().0,
1135+
&mut error,
1136+
);
1137+
debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
1138+
if error.is_null() {
1139+
Ok(())
1140+
} else {
1141+
Err(from_glib_full(error))
1142+
}
1143+
}
1144+
}
11141145
}
11151146

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

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::FileAttributeValue;
4647
mod file_attribute_info;
4748
pub use crate::file_attribute_info::FileAttributeInfo;
4849
mod file_attribute_info_list;

0 commit comments

Comments
 (0)