taskchampion-rb 0.9.1 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Cargo.lock +140 -1324
- data/ext/taskchampion/Cargo.toml +1 -1
- data/ext/taskchampion/src/error.rs +0 -8
- data/ext/taskchampion/src/replica.rs +1 -1
- data/ext/taskchampion/src/task.rs +22 -12
- data/ext/taskchampion/src/thread_check.rs +2 -2
- data/ext/taskchampion/src/util.rs +0 -23
- data/lib/taskchampion/version.rb +1 -1
- metadata +3 -3
- /data/{TaskchampionRbErrors.md → docs/TaskchampionRbErrors.md} +0 -0
data/ext/taskchampion/Cargo.toml
CHANGED
|
@@ -12,7 +12,7 @@ crate-type = ["cdylib"]
|
|
|
12
12
|
[dependencies]
|
|
13
13
|
magnus = { version = "0.7", features = ["rb-sys"] }
|
|
14
14
|
rb-sys = "0.9.103"
|
|
15
|
-
taskchampion = "2.0"
|
|
15
|
+
taskchampion = { version = "2.0", default-features = false, features = ["server-sync", "server-gcp"] }
|
|
16
16
|
chrono = "0.4"
|
|
17
17
|
uuid = "1.0"
|
|
18
18
|
|
|
@@ -11,14 +11,6 @@ pub fn init_errors(module: &RModule) -> Result<(), Error> {
|
|
|
11
11
|
Ok(())
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
pub fn base_error() -> magnus::ExceptionClass {
|
|
15
|
-
let ruby = magnus::Ruby::get().expect("Ruby not available");
|
|
16
|
-
let module = ruby.class_object().const_get::<_, RModule>("Taskchampion")
|
|
17
|
-
.expect("Taskchampion module not found");
|
|
18
|
-
module.const_get::<_, magnus::ExceptionClass>("Error")
|
|
19
|
-
.expect("Error class not initialized")
|
|
20
|
-
}
|
|
21
|
-
|
|
22
14
|
pub fn thread_error() -> magnus::ExceptionClass {
|
|
23
15
|
let ruby = magnus::Ruby::get().expect("Ruby not available");
|
|
24
16
|
let module = ruby.class_object().const_get::<_, RModule>("Taskchampion")
|
|
@@ -58,7 +58,7 @@ impl Replica {
|
|
|
58
58
|
let tc_task = tc_replica.create_task(tc_uuid, &mut tc_ops).map_err(into_error)?;
|
|
59
59
|
|
|
60
60
|
// Add the resulting operations to the provided Operations object
|
|
61
|
-
operations.extend_from_tc(tc_ops)
|
|
61
|
+
operations.extend_from_tc(tc_ops)?;
|
|
62
62
|
|
|
63
63
|
// Convert to Ruby Task object
|
|
64
64
|
let task = Task::from_tc_task(tc_task);
|
|
@@ -137,24 +137,22 @@ impl Task {
|
|
|
137
137
|
|
|
138
138
|
fn get_uda(&self, namespace: String, key: String) -> Result<Value, Error> {
|
|
139
139
|
let task = self.0.get()?;
|
|
140
|
-
|
|
140
|
+
let combined_key = if namespace.is_empty() { key } else { format!("{}.{}", namespace, key) };
|
|
141
|
+
match task.get_user_defined_attribute(&combined_key) {
|
|
141
142
|
Some(value) => Ok(value.into_value()),
|
|
142
|
-
None => Ok(().into_value()),
|
|
143
|
+
None => Ok(().into_value()),
|
|
143
144
|
}
|
|
144
145
|
}
|
|
145
146
|
|
|
146
147
|
fn udas(&self) -> Result<RArray, Error> {
|
|
147
148
|
let task = self.0.get()?;
|
|
148
|
-
let udas: Vec<(
|
|
149
|
-
.map(|(
|
|
149
|
+
let udas: Vec<(String, String)> = task.get_user_defined_attributes()
|
|
150
|
+
.map(|(key, value)| (key.to_string(), value.to_string()))
|
|
150
151
|
.collect();
|
|
151
152
|
|
|
152
|
-
vec_to_ruby(udas, |(
|
|
153
|
+
vec_to_ruby(udas, |(key, value)| {
|
|
153
154
|
let array = RArray::new();
|
|
154
|
-
|
|
155
|
-
key_array.push(key_tuple.0)?;
|
|
156
|
-
key_array.push(key_tuple.1)?;
|
|
157
|
-
array.push(key_array)?;
|
|
155
|
+
array.push(key)?;
|
|
158
156
|
array.push(value)?;
|
|
159
157
|
Ok(array.into_value())
|
|
160
158
|
})
|
|
@@ -305,6 +303,15 @@ impl Task {
|
|
|
305
303
|
Ok(())
|
|
306
304
|
}
|
|
307
305
|
|
|
306
|
+
fn set_modified(&self, modified: Value, operations: &crate::operations::Operations) -> Result<(), Error> {
|
|
307
|
+
let mut task = self.0.get_mut()?;
|
|
308
|
+
let modified_datetime = ruby_to_datetime(modified)?;
|
|
309
|
+
operations.with_inner_mut(|ops| {
|
|
310
|
+
task.set_modified(modified_datetime, ops)
|
|
311
|
+
})?;
|
|
312
|
+
Ok(())
|
|
313
|
+
}
|
|
314
|
+
|
|
308
315
|
fn set_value(&self, property: String, value: Value, operations: &crate::operations::Operations) -> Result<(), Error> {
|
|
309
316
|
if property.trim().is_empty() {
|
|
310
317
|
return Err(Error::new(
|
|
@@ -360,7 +367,7 @@ impl Task {
|
|
|
360
367
|
Some(timestamp_str) => {
|
|
361
368
|
// Parse the string as Unix timestamp (seconds since epoch)
|
|
362
369
|
if let Ok(timestamp_secs) = timestamp_str.parse::<i64>() {
|
|
363
|
-
use chrono::
|
|
370
|
+
use chrono::DateTime;
|
|
364
371
|
if let Some(dt) = DateTime::from_timestamp(timestamp_secs, 0) {
|
|
365
372
|
return datetime_to_ruby(dt);
|
|
366
373
|
}
|
|
@@ -387,8 +394,9 @@ impl Task {
|
|
|
387
394
|
}
|
|
388
395
|
|
|
389
396
|
let mut task = self.0.get_mut()?;
|
|
397
|
+
let combined_key = format!("{}.{}", namespace, key);
|
|
390
398
|
operations.with_inner_mut(|ops| {
|
|
391
|
-
task.
|
|
399
|
+
task.set_user_defined_attribute(&combined_key, &value, ops)
|
|
392
400
|
})?;
|
|
393
401
|
Ok(())
|
|
394
402
|
}
|
|
@@ -408,8 +416,9 @@ impl Task {
|
|
|
408
416
|
}
|
|
409
417
|
|
|
410
418
|
let mut task = self.0.get_mut()?;
|
|
419
|
+
let combined_key = format!("{}.{}", namespace, key);
|
|
411
420
|
operations.with_inner_mut(|ops| {
|
|
412
|
-
task.
|
|
421
|
+
task.remove_user_defined_attribute(&combined_key, ops)
|
|
413
422
|
})?;
|
|
414
423
|
Ok(())
|
|
415
424
|
}
|
|
@@ -480,6 +489,7 @@ pub fn init(module: &RModule) -> Result<(), Error> {
|
|
|
480
489
|
class.define_method("add_annotation_with_timestamp", method!(Task::add_annotation_with_timestamp, 3))?;
|
|
481
490
|
class.define_method("set_due", method!(Task::set_due, 2))?;
|
|
482
491
|
class.define_method("set_entry", method!(Task::set_entry, 2))?;
|
|
492
|
+
class.define_method("set_modified", method!(Task::set_modified, 2))?;
|
|
483
493
|
class.define_method("set_value", method!(Task::set_value, 3))?;
|
|
484
494
|
class.define_method("set_timestamp", method!(Task::set_timestamp, 3))?;
|
|
485
495
|
class.define_method("get_timestamp", method!(Task::get_timestamp, 1))?;
|
|
@@ -32,12 +32,12 @@ impl<T> ThreadBound<T> {
|
|
|
32
32
|
Ok(())
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
pub fn get(&self) -> Result<std::cell::Ref<T>, Error> {
|
|
35
|
+
pub fn get(&self) -> Result<std::cell::Ref<'_, T>, Error> {
|
|
36
36
|
self.check_thread()?;
|
|
37
37
|
Ok(self.inner.borrow())
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
pub fn get_mut(&self) -> Result<std::cell::RefMut<T>, Error> {
|
|
40
|
+
pub fn get_mut(&self) -> Result<std::cell::RefMut<'_, T>, Error> {
|
|
41
41
|
self.check_thread()?;
|
|
42
42
|
Ok(self.inner.borrow_mut())
|
|
43
43
|
}
|
|
@@ -31,8 +31,6 @@ pub fn datetime_to_ruby(dt: DateTime<Utc>) -> Result<Value, Error> {
|
|
|
31
31
|
|
|
32
32
|
/// Convert Ruby DateTime/Time/String to Rust DateTime<Utc> with enhanced validation
|
|
33
33
|
pub fn ruby_to_datetime(value: Value) -> Result<DateTime<Utc>, Error> {
|
|
34
|
-
let ruby = magnus::Ruby::get().map_err(|e| Error::new(magnus::exception::runtime_error(), e.to_string()))?;
|
|
35
|
-
|
|
36
34
|
// If it's a string, parse it
|
|
37
35
|
if let Ok(s) = RString::try_convert(value) {
|
|
38
36
|
let s = unsafe { s.as_str()? };
|
|
@@ -99,15 +97,6 @@ where
|
|
|
99
97
|
}
|
|
100
98
|
}
|
|
101
99
|
|
|
102
|
-
/// Convert HashMap to Ruby Hash
|
|
103
|
-
pub fn hashmap_to_ruby(map: HashMap<String, String>) -> Result<RHash, Error> {
|
|
104
|
-
let hash = RHash::new();
|
|
105
|
-
for (k, v) in map {
|
|
106
|
-
hash.aset(k, v)?;
|
|
107
|
-
}
|
|
108
|
-
Ok(hash)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
100
|
/// Convert Ruby Hash to HashMap
|
|
112
101
|
pub fn ruby_to_hashmap(hash: RHash) -> Result<HashMap<String, String>, Error> {
|
|
113
102
|
let mut map = HashMap::new();
|
|
@@ -130,15 +119,3 @@ where
|
|
|
130
119
|
Ok(array)
|
|
131
120
|
}
|
|
132
121
|
|
|
133
|
-
/// Convert Ruby Array to Vec
|
|
134
|
-
pub fn ruby_to_vec<T, F>(array: RArray, converter: F) -> Result<Vec<T>, Error>
|
|
135
|
-
where
|
|
136
|
-
F: Fn(Value) -> Result<T, Error>,
|
|
137
|
-
{
|
|
138
|
-
let mut vec = Vec::with_capacity(array.len());
|
|
139
|
-
for i in 0..array.len() {
|
|
140
|
-
let value: Value = array.entry(i as isize)?;
|
|
141
|
-
vec.push(converter(value)?);
|
|
142
|
-
}
|
|
143
|
-
Ok(vec)
|
|
144
|
-
}
|
data/lib/taskchampion/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: taskchampion-rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tim Case
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rb_sys
|
|
@@ -41,10 +41,10 @@ files:
|
|
|
41
41
|
- Cargo.toml
|
|
42
42
|
- README.md
|
|
43
43
|
- Rakefile
|
|
44
|
-
- TaskchampionRbErrors.md
|
|
45
44
|
- docs/ANNOTATION_IMPLEMENTATION.md
|
|
46
45
|
- docs/API_REFERENCE.md
|
|
47
46
|
- docs/THREAD_SAFETY.md
|
|
47
|
+
- docs/TaskchampionRbErrors.md
|
|
48
48
|
- docs/breakthrough.md
|
|
49
49
|
- docs/date_conversion_analysis.md
|
|
50
50
|
- docs/description.md
|
|
File without changes
|