|
1 | 1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | 2 |
|
3 | | -use std::{cell::RefCell, mem, pin::Pin, ptr}; |
| 3 | +use std::{cell::RefCell, ffi::CStr, mem, pin::Pin, ptr}; |
4 | 4 |
|
5 | 5 | use glib::{prelude::*, translate::*}; |
6 | 6 |
|
7 | 7 | #[cfg(feature = "v2_74")] |
8 | 8 | use crate::FileIOStream; |
9 | | -use crate::{ffi, Cancellable, File, FileCreateFlags, FileEnumerator, FileQueryInfoFlags}; |
| 9 | +use crate::{ |
| 10 | + ffi, Cancellable, File, FileAttributeType, FileCreateFlags, FileEnumerator, FileQueryInfoFlags, |
| 11 | +}; |
10 | 12 |
|
11 | 13 | impl File { |
12 | 14 | #[cfg(feature = "v2_74")] |
@@ -1111,6 +1113,171 @@ pub trait FileExtManual: IsA<File> + Sized { |
1111 | 1113 |
|
1112 | 1114 | (fut, Box::pin(receiver)) |
1113 | 1115 | } |
| 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 | + } |
1114 | 1144 | } |
1115 | 1145 |
|
1116 | 1146 | 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 | +} |
0 commit comments