@@ -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