Skip to content

Commit 8f9d700

Browse files
committed
fix(hf): support config from options
1 parent ce9f1d8 commit 8f9d700

File tree

2 files changed

+61
-10
lines changed

2 files changed

+61
-10
lines changed

.github/workflows/ci_core.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ jobs:
9494
cargo update zerofrom --precise 0.1.5
9595
cargo update idna_adapter --precise 1.2.0
9696
cargo update litemap --precise 0.7.4
97-
cargo update ctor --precise 0.6.1
97+
cargo update ctor@0.6.3 --precise 0.6.1
9898
cargo +${OPENDAL_MSRV} clippy -- -D warnings
9999
100100
build_default_features:

core/services/huggingface/src/config.rs

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,11 @@ impl opendal_core::Configurator for HfConfig {
7777
type Builder = HfBuilder;
7878

7979
fn from_uri(uri: &opendal_core::OperatorUri) -> opendal_core::Result<Self> {
80+
let opts = uri.options();
81+
8082
// Reconstruct the full path from authority (name) and root.
81-
// OperatorUri splits "hf://datasets/user/repo" into
82-
// name="datasets" and root="user/repo".
83+
// OperatorUri splits "hf://datasets/user/repo@rev/path" into
84+
// name="datasets" and root="user/repo@rev/path".
8385
let mut path = String::new();
8486
if let Some(name) = uri.name() {
8587
if !name.is_empty() {
@@ -95,13 +97,35 @@ impl opendal_core::Configurator for HfConfig {
9597
}
9698
}
9799

98-
let parsed = HfUri::parse(&path)?;
99-
Ok(Self {
100-
repo_type: parsed.repo.repo_type,
101-
repo_id: Some(parsed.repo.repo_id),
102-
revision: parsed.repo.revision,
103-
..Default::default()
104-
})
100+
if !path.is_empty() {
101+
// Full URI like "hf://datasets/user/repo@rev/path"
102+
let parsed = HfUri::parse(&path)?;
103+
Ok(Self {
104+
repo_type: parsed.repo.repo_type,
105+
repo_id: Some(parsed.repo.repo_id),
106+
revision: parsed.repo.revision,
107+
token: opts.get("token").cloned(),
108+
endpoint: opts.get("endpoint").cloned(),
109+
..Default::default()
110+
})
111+
} else {
112+
// Bare scheme from via_iter, all config is in options.
113+
let repo_type = opts
114+
.get("repo_type")
115+
.map(|s| RepoType::parse(s))
116+
.transpose()?
117+
.unwrap_or_default();
118+
Ok(Self {
119+
repo_type,
120+
repo_id: opts.get("repo_id").cloned(),
121+
revision: opts.get("revision").cloned(),
122+
root: opts.get("root").cloned(),
123+
token: opts.get("token").cloned(),
124+
endpoint: opts.get("endpoint").cloned(),
125+
xet: opts.get("xet").is_some_and(|v| v == "true"),
126+
..Default::default()
127+
})
128+
}
105129
}
106130

107131
fn into_builder(self) -> Self::Builder {
@@ -130,4 +154,31 @@ mod tests {
130154
assert_eq!(cfg.revision.as_deref(), Some("dev"));
131155
assert!(cfg.root.is_none());
132156
}
157+
158+
#[test]
159+
fn from_uri_via_iter_options() {
160+
use opendal_core::Configurator;
161+
use opendal_core::OperatorUri;
162+
163+
// Simulates the via_iter path: bare scheme with options map.
164+
let uri = OperatorUri::new(
165+
"huggingface",
166+
vec![
167+
("repo_type".to_string(), "dataset".to_string()),
168+
(
169+
"repo_id".to_string(),
170+
"opendal/huggingface-testdata".to_string(),
171+
),
172+
("revision".to_string(), "main".to_string()),
173+
("root".to_string(), "/testdata/".to_string()),
174+
],
175+
)
176+
.unwrap();
177+
178+
let cfg = HfConfig::from_uri(&uri).unwrap();
179+
assert_eq!(cfg.repo_type, RepoType::Dataset);
180+
assert_eq!(cfg.repo_id.as_deref(), Some("opendal/huggingface-testdata"));
181+
assert_eq!(cfg.revision.as_deref(), Some("main"));
182+
assert_eq!(cfg.root.as_deref(), Some("/testdata/"));
183+
}
133184
}

0 commit comments

Comments
 (0)