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.
@@ -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
- match task.get_uda(&namespace, &key) {
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()), // () converts to nil in Magnus
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<((String, String), String)> = task.get_udas()
149
- .map(|((ns, key), value)| ((ns.to_string(), key.to_string()), value.to_string()))
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, |(key_tuple, value)| {
153
+ vec_to_ruby(udas, |(key, value)| {
153
154
  let array = RArray::new();
154
- let key_array = RArray::new();
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::{DateTime, Utc};
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.set_uda(&namespace, &key, &value, ops)
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.remove_uda(&namespace, &key, ops)
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
- }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Taskchampion
4
- VERSION = "0.9.1"
4
+ VERSION = "0.9.3"
5
5
  end
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.1
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-23 00:00:00.000000000 Z
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