1# Copyright 2019 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Conversions between snake-, camel-, and shouty-case names.""" 16 17from enum import Enum 18 19 20class Case(str, Enum): 21 SNAKE = "snake_case" 22 SHOUTY = "SHOUTY_CASE" 23 CAMEL = "CamelCase" 24 K_CAMEL = "kCamelCase" 25 26 27# Map of (from, to) cases to their conversion function. Initially only contains 28# identity case conversions, additional conversions are added with the 29# _case_conversion decorator. 30_case_conversions = {(case.value, case.value): lambda x: x for case in Case} 31 32 33def _case_conversion(case_from, case_to): 34 """Decorator to dynamically dispatch case conversions at runtime.""" 35 def _func(f): 36 _case_conversions[case_from, case_to] = f 37 return f 38 39 return _func 40 41 42@_case_conversion(Case.SNAKE, Case.CAMEL) 43@_case_conversion(Case.SHOUTY, Case.CAMEL) 44def snake_to_camel(name): 45 """Convert from snake_case to CamelCase. Also works from SHOUTY_CASE.""" 46 return "".join(word.capitalize() for word in name.split("_")) 47 48 49@_case_conversion(Case.CAMEL, Case.K_CAMEL) 50def camel_to_k_camel(name): 51 """Convert from CamelCase to kCamelCase.""" 52 return "k" + name 53 54 55@_case_conversion(Case.SNAKE, Case.K_CAMEL) 56@_case_conversion(Case.SHOUTY, Case.K_CAMEL) 57def snake_to_k_camel(name): 58 """Converts from snake_case to kCamelCase. Also works from SHOUTY_CASE.""" 59 return camel_to_k_camel(snake_to_camel(name)) 60 61 62def convert_case(case_from, case_to, value): 63 """Converts cases based on runtime case values. 64 65 Note: Cases can be strings or enum values.""" 66 return _case_conversions[case_from, case_to](value) 67 68 69def is_case_conversion_supported(case_from, case_to): 70 """Determines if a case conversion would be supported""" 71 return (case_from, case_to) in _case_conversions 72