@@ -537,6 +537,40 @@ impl CacheConfigs {
537537 ( cache_type, fallback)
538538 }
539539
540+ /// Look up a remote cache type by name (e.g. "s3", "gha").
541+ /// Returns `Ok((display_name, Some(..)))` if the name is known and configured,
542+ /// `Ok((display_name, None))` if known but not configured, `Err` if unknown.
543+ pub fn cache_type_by_name ( & self , name : & str ) -> Result < ( & ' static str , Option < CacheType > ) > {
544+ match name {
545+ #[ cfg( feature = "s3" ) ]
546+ "s3" => Ok ( ( "S3" , self . s3 . clone ( ) . map ( CacheType :: S3 ) ) ) ,
547+ #[ cfg( feature = "redis" ) ]
548+ "redis" => Ok ( ( "Redis" , self . redis . clone ( ) . map ( CacheType :: Redis ) ) ) ,
549+ #[ cfg( feature = "memcached" ) ]
550+ "memcached" => Ok ( (
551+ "Memcached" ,
552+ self . memcached . clone ( ) . map ( CacheType :: Memcached ) ,
553+ ) ) ,
554+ #[ cfg( feature = "gcs" ) ]
555+ "gcs" => Ok ( ( "GCS" , self . gcs . clone ( ) . map ( CacheType :: GCS ) ) ) ,
556+ #[ cfg( feature = "gha" ) ]
557+ "gha" => Ok ( ( "GHA" , self . gha . clone ( ) . map ( CacheType :: GHA ) ) ) ,
558+ #[ cfg( feature = "azure" ) ]
559+ "azure" => Ok ( ( "Azure" , self . azure . clone ( ) . map ( CacheType :: Azure ) ) ) ,
560+ #[ cfg( feature = "webdav" ) ]
561+ "webdav" => Ok ( ( "WebDAV" , self . webdav . clone ( ) . map ( CacheType :: Webdav ) ) ) ,
562+ #[ cfg( feature = "oss" ) ]
563+ "oss" => Ok ( ( "OSS" , self . oss . clone ( ) . map ( CacheType :: OSS ) ) ) ,
564+ #[ cfg( feature = "cos" ) ]
565+ "cos" => Ok ( ( "COS" , self . cos . clone ( ) . map ( CacheType :: COS ) ) ) ,
566+ _ => bail ! (
567+ "Unknown cache level: '{}' (may require a feature flag, e.g. --features {})" ,
568+ name,
569+ name
570+ ) ,
571+ }
572+ }
573+
540574 /// Get ordered list of cache types based on configured levels.
541575 /// If levels are specified, returns them in order with validation.
542576 /// If no levels specified and single remote cache, returns that single cache.
@@ -547,42 +581,17 @@ impl CacheConfigs {
547581 let mut caches = Vec :: new ( ) ;
548582 for level_name in & ml_config. chain {
549583 let level_name = level_name. trim ( ) ;
550- let cache_type = match level_name {
551- "s3" => self . s3 . clone ( ) . map ( CacheType :: S3 ) . ok_or_else ( || {
552- anyhow ! ( "S3 cache not configured but specified in levels" )
553- } ) ?,
554- "redis" => self . redis . clone ( ) . map ( CacheType :: Redis ) . ok_or_else ( || {
555- anyhow ! ( "Redis cache not configured but specified in levels" )
556- } ) ?,
557- "memcached" => self
558- . memcached
559- . clone ( )
560- . map ( CacheType :: Memcached )
561- . ok_or_else ( || {
562- anyhow ! ( "Memcached cache not configured but specified in levels" )
563- } ) ?,
564- "gcs" => self . gcs . clone ( ) . map ( CacheType :: GCS ) . ok_or_else ( || {
565- anyhow ! ( "GCS cache not configured but specified in levels" )
566- } ) ?,
567- "gha" => self . gha . clone ( ) . map ( CacheType :: GHA ) . ok_or_else ( || {
568- anyhow ! ( "GHA cache not configured but specified in levels" )
569- } ) ?,
570- "azure" => self . azure . clone ( ) . map ( CacheType :: Azure ) . ok_or_else ( || {
571- anyhow ! ( "Azure cache not configured but specified in levels" )
572- } ) ?,
573- "webdav" => self . webdav . clone ( ) . map ( CacheType :: Webdav ) . ok_or_else ( || {
574- anyhow ! ( "Webdav cache not configured but specified in levels" )
575- } ) ?,
576- "oss" => self . oss . clone ( ) . map ( CacheType :: OSS ) . ok_or_else ( || {
577- anyhow ! ( "OSS cache not configured but specified in levels" )
578- } ) ?,
579- "disk" => {
580- // Disk cache is handled separately in MultiLevelStorage::from_config
581- // Mark it by continuing - it will be added to the storage list there
582- continue ;
583- }
584- _ => bail ! ( "Unknown cache level: {}" , level_name) ,
585- } ;
584+ if level_name == "disk" {
585+ // Disk cache is handled separately in MultiLevelStorage::from_config
586+ continue ;
587+ }
588+ let ( display_name, cache_type) = self . cache_type_by_name ( level_name) ?;
589+ let cache_type = cache_type. ok_or_else ( || {
590+ anyhow ! (
591+ "{} cache not configured but specified in levels" ,
592+ display_name
593+ )
594+ } ) ?;
586595 caches. push ( cache_type) ;
587596 }
588597 Ok ( caches)
@@ -2858,10 +2867,10 @@ fn test_get_cache_levels_missing_config() {
28582867
28592868 let result = configs. get_cache_levels ( ) ;
28602869 assert ! ( result. is_err( ) ) ;
2870+ let err = result. unwrap_err ( ) . to_string ( ) ;
2871+ // With the s3 feature, we get "not configured"; without it, "unknown cache level"
28612872 assert ! (
2862- result
2863- . unwrap_err( )
2864- . to_string( )
2865- . contains( "S3 cache not configured" )
2873+ err. contains( "S3 cache not configured" ) || err. contains( "Unknown cache level" ) ,
2874+ "unexpected error: {err}"
28662875 ) ;
28672876}
0 commit comments