1818
1919import re
2020from collections import defaultdict
21+ from functools import singledispatch
22+ from typing import Any , TypeVar
2123
2224from beets import library , ui
2325from beets .plugins import BeetsPlugin
2426
27+ T = TypeVar ("T" )
28+
29+
30+ @singledispatch
31+ def rewrite_value (value : Any , pat : re .Pattern [str ], repl : str ) -> Any :
32+ """Rewrite a value if it matches the given pattern."""
33+ return value
34+
35+
36+ @rewrite_value .register
37+ def _ (value : str , pat : re .Pattern [str ], repl : str ) -> str :
38+ if pat .match (value .lower ()):
39+ return repl
40+ return value
41+
42+
43+ @rewrite_value .register (list )
44+ def _ (value : list [str ], pat : re .Pattern [str ], repl : str ) -> list [str ]:
45+ return [rewrite_value (v , pat , repl ) for v in value ]
46+
47+
48+ def apply_rewrite_rules (
49+ value : T , rules : list [tuple [re .Pattern [str ], str ]]
50+ ) -> T :
51+ """Apply the first matching rewrite rule to the given value."""
52+ for pattern , replacement in rules :
53+ if (new_value := rewrite_value (value , pattern , replacement )) != value :
54+ # Rewrite activated.
55+ return new_value
56+ # Not activated; return original value.
57+ return value
58+
2559
2660def rewriter (field , rules ):
2761 """Create a template field function that rewrites the given field
@@ -30,13 +64,7 @@ def rewriter(field, rules):
3064 """
3165
3266 def fieldfunc (item ):
33- value = item ._values_fixed [field ]
34- for pattern , replacement in rules :
35- if pattern .match (value .lower ()):
36- # Rewrite activated.
37- return replacement
38- # Not activated; return original value.
39- return value
67+ return apply_rewrite_rules (item ._values_fixed [field ], rules )
4068
4169 return fieldfunc
4270
0 commit comments