Skip to content

Commit b4c17ae

Browse files
committed
fix(opencode): restore Result return type and scope timestamp extraction
- Restore read_message_file to return Result<Option<LoadedEntry>> so IO errors are propagated instead of silently converted to None. - Scope extract_message_timestamp to time.created by finding the "time" key first before searching for "created": to avoid false positives from other created keys in the JSON.
1 parent b6c7bc0 commit b4c17ae

1 file changed

Lines changed: 12 additions & 8 deletions

File tree

  • rust/crates/ccusage/src/adapter/opencode

‎rust/crates/ccusage/src/adapter/opencode/loader.rs‎

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub(crate) fn load_entries_from_directory(
7272
collect_files_with_extension(&messages_dir, "json", &mut files);
7373
for file in files {
7474
if let Some(entry) =
75-
read_message_file(&file, tz.as_ref(), shared.mode, pricing.as_ref(), shared)
75+
read_message_file(&file, tz.as_ref(), shared.mode, pricing.as_ref(), shared)?
7676
{
7777
if let Some(id) = entry_id(&entry) {
7878
if !seen.insert(id.to_string()) {
@@ -184,26 +184,30 @@ fn read_message_file(
184184
mode: CostMode,
185185
pricing: Option<&PricingMap>,
186186
shared: &SharedArgs,
187-
) -> Option<LoadedEntry> {
188-
let content = std::fs::read_to_string(path).ok()?;
187+
) -> Result<Option<LoadedEntry>> {
188+
let content = std::fs::read_to_string(path)?;
189189
if let Some(millis) = extract_message_timestamp(&content) {
190190
if !timestamp_within_range(millis, tz, shared) {
191-
return None;
191+
return Ok(None);
192192
}
193193
}
194194
let Ok(value) = serde_json::from_str::<Value>(&content) else {
195-
return None;
195+
return Ok(None);
196196
};
197-
message_value_to_entry(&value, None, None, tz, mode, pricing)
197+
Ok(message_value_to_entry(
198+
&value, None, None, tz, mode, pricing,
199+
))
198200
}
199201

200202
fn entry_id(entry: &LoadedEntry) -> Option<&str> {
201203
entry.data.message.id.as_deref().filter(|id| !id.is_empty())
202204
}
203205

204206
fn extract_message_timestamp(data: &str) -> Option<i64> {
205-
let start = data.find("\"created\":")?;
206-
let after_key = data[start + "\"created\":".len()..].trim_start();
207+
let time_start = data.find("\"time\"")?;
208+
let time_section = &data[time_start..];
209+
let created_start = time_section.find("\"created\":")?;
210+
let after_key = time_section[created_start + "\"created\":".len()..].trim_start();
207211
let end = after_key.find(|c: char| !c.is_ascii_digit())?;
208212
after_key[..end].parse::<i64>().ok()
209213
}

0 commit comments

Comments
 (0)