TypeList 之 Replace,把类型列表中的 T 类型换成 U 类型

#include <cstdlib>
#include <iostream>

using namespace std;
class NullType;
namespace TL
{
  template<class T,class U>
  struct TypeList
  {
    typedef T head;
    typedef U tail;
  };
  #define TYPELIST_1(T1) TypeList<T1,NullType>
  #define TYPELIST_2(T1,T2) TypeList<T1,TYPELIST_1(T2)>
  #define TYPELIST_3(T1,T2,T3) TypeList<T1,TYPELIST_2(T2,T3)>
  #define TYPELIST_4(T1,T2,T3,T4) TypeList<T1,TYPELIST_3(T2,T3,T4)>
  //-----------------------------------------------------------------
  //Length
  template<class Tlist>struct Length;
  template<>struct Length<NullType>
  {
    enum{value = 0};
  };
  template<class T,class U>
  struct Length<TypeList<T,U> >
  {
    enum{value = 1 + Length<U>::value};
  };
  //---------------------------------------------------------------
  //利用索引查找对象
  template<class T,int U>struct TypeAt;
  template<class head,class tail>
  struct TypeAt<TypeList<head,tail>,0>
  {
    typedef head Result;
  };
  template<class head,class tail,int i>
  struct TypeAt<TypeList<head,tail>,i>
  {
    typedef typename TypeAt<tail,i - 1>::Result Result;
  };
  //---------------------------------------------------------------
  //indexof
  template<class TList,class T>struct IndexOf;
  template<class T>
  struct IndexOf<NullType,T>
  {
    enum{value = -1};
  };
  template<class Tail,class T>
  struct IndexOf<TypeList<T,Tail>,T>
  {
    enum{value = 0};
  };
  template<class Head,class Tail,class T>
  struct IndexOf<TypeList<Head,Tail>,T>
  {
  private:
    enum{temp = IndexOf<Tail,T>::value};
  public:
    enum{value = temp == -1 ? -1 : 1 + temp};
  };
  //---------------------------------------------------------------
  //Append
  template<class TList,class T>struct Append;
  template<>
  struct Append<NullType,NullType>
  {
    typedef NullType Result;
  };
  template<class T>
  struct Append<NullType,T>
  {
    typedef TYPELIST_1(T) Result;
  };
  template<class head,class Tail>
  struct Append<NullType,TypeList<head,Tail> >
  {
    typedef TypeList<head,Tail> Result;
  };
  template<class head,class Tail,class T>
  struct Append<TypeList<head,Tail>,T>
  {
    typedef TypeList<head,typename Append<Tail,T>::Result> Result;
  };
  //---------------------------------------------------------------
  //Erase
  template<class TList,class T>struct Erase;
  template<class T>
  struct Erase<NullType,T>
  {
    typedef NullType Result;
  };
  template<class T,class tail>
  struct Erase<TypeList<T,tail>,T>
  {
    typedef tail Result;
  };
  template<class head,class tail,class T>
  struct Erase<TypeList<head,tail>,T>
  {
    typedef TypeList<head,typename Erase<tail,T>::Result> Result;
  };
  //---------------------------------------------------------------
  //NoDuplicate
  template<class TList>struct NoDuplicate;
  template<>struct NoDuplicate<NullType>
  {
    typedef NullType Result;
  };
  template<class head,class tail>
  struct NoDuplicate<TypeList<head,tail> >
  {
  private:
    typedef typename NoDuplicate<tail>::Result L1;
    typedef typename Erase<L1,head>::Result L2;
  public:
    typedef TypeList<head,L2> Result;
  };
  //---------------------------------------------------------------
  //TypeList 之 Replace,把类型列表中的 T 类型换成 U 类型
  template<class TList,class T,class U>struct Replace;
  template<class T,class U>
  struct Replace<NullType,T,U>
  {
    typedef NullType Result;
  };
  template<class T,class U,class tail>
  struct Replace<TypeList<T,tail>,T,U>
  {
    typedef TypeList<U,tail> Result;
  };
  template<class head,class tail,class T,class U>
  struct Replace<TypeList<head,tail>,T,U>
  {
    typedef TypeList<head,typename Replace<tail,T,U>::Result> Result;
  };
}
using namespace TL;
int main(int argc, char *argv[])
{
    typedef TYPELIST_4(int,float,char,double) Test1;
    Test1::head n = 1011;
    cout<<"替换类型之前是整数类型,其值 = "<<n<<endl;
    typedef Replace<Test1,int,unsigned char>::Result TestRes;
    TestRes::head cc[] = "现在变成 char 了";
    cout<<"替换类型之后是char类型,其值 = "<<cc<<endl;
    system("PAUSE");
    return EXIT_SUCCESS;
}

把这部分代码BASE_TEMPLATE = { "app_category": "", # 运行时自动填 "config": { "ttl": 1, "visible_quantity": 128, "multilingual_vocabularys": [""], "support_multiLanguage":False, "enable_persistent":True, "app_payload_builder_list":["tapoApnsPayloadBuilder","tapoFcmPayloadBuilder"], "msgSubType": [""] }, "scenario_list": ["PUSH_NOTIFICATION", "PERSISTENCE_NOTIFICATION"], "default_locale": "en" } the_merge_map = bean2Map.get_merge_map() the_halo_merge_map = haloBean2Map.get_merge_map() msg_persistant_day_list = [ {"day": 1, "msgType-set": ["default"]}, {"day": 3, "msgType-set": ["NEW_DEVICE_JOINED", "aginetGamingBoostActivated"]}]app_category_to_multi_language_msg_type_map = {}app_category_to_msgType_map = {}multi_lang_set=[]def is_match(nt, key): """判断是否完全匹配或带下划线的前缀匹配""" return nt == key or nt.startswith(key + "_") def get_ttl(notification_type, ttl_mapping, default_ttl): """查找匹配的TTL值(支持直接匹配和带下划线前缀匹配)""" for key in sorted(ttl_mapping.keys(), key=lambda k: -len(k)): # 按键长降序遍历 if is_match(notification_type, key): return ttl_mapping[key] return default_ttl # 默认TTL TTL_MAPPING = {} for entry in msg_persistant_day_list: day = entry["day"] for msg_type in entry["msgType-set"]: TTL_MAPPING[msg_type.strip()] = day def set_support_multiLanguage(appCategory, notificationType): if appCategory == "vigi": # 新增条件:如果 notificationType 以 "8_" 开头,则返回 False if notificationType.startswith("8_") or notificationType == "common" or notificationType == "multiple": return False return True # 否则,vigi 类型默认支持多语言 if appCategory == "omadaGuard": if notificationType.startswith("8_") or notificationType == "common" or notificationType == "multiple": return False return True # 从全局字典中获取对应 appCategory 的列表,若不存在则返回空列表 category_list = app_category_to_multi_language_msg_type_map.get(appCategory, []) if appCategory == "common": # 遍历 default 列表并应用前缀匹配逻辑 for key in app_category_to_multi_language_msg_type_map.get("default", []): if is_match(notificationType, key): return True return False # 无匹配时返回 False return check_notification_type(notificationType, category_list, app_category_to_multi_language_msg_type_map) def check_notification_type(notification_type, category_list, app_category_map): # 直接匹配条件 if notification_type in category_list or notification_type in app_category_map.get("default", []): return True def is_match(nt, key): return nt == key or nt.startswith(key + "_") # 完全匹配或带下划线的前缀匹配 # 1. 检查 category_list 的前缀匹配 for key in category_list: if is_match(notification_type, key): return True # 2. 检查 app_category_map.default 的前缀匹配 for key in app_category_map.get("default", []): if is_match(notification_type, key): return True # 3. 检查 app_category_map 其他键的最长前缀匹配(按键长降序) for key in sorted(app_category_map.keys(), key=lambda k: -len(k)): if key == "default": continue if is_match(notification_type, key): return True return False def set_enble_persistent(appCategory, notificationType): if appCategory == "vigi": if notificationType.startswith("8_") or notificationType == "common" or notificationType == "multiple": return False return True if appCategory == "omadaGuard": if notificationType.startswith("8_") or notificationType == "common" or notificationType == "multiple": return False return True if appCategory == "kidshield" or appCategory == "common" or appCategory == "verification" or appCategory == "omada": return False # 获取appCategory对应的消息列表 category_list = app_category_to_msgType_map.get(appCategory) if category_list is None: # 不在map中的app类型直接返回True return True return match_enable_persistent(notificationType, category_list) def match_enable_persistent(notification_type, category_list): if notification_type in category_list: return True for key in category_list: if is_match(notification_type, key): return True return False def load_visible_quantity_map(file_path): mapping = {} with open(file_path, "r", encoding="utf-8") as f: for line in f: stripped = line.strip() if not stripped or stripped.startswith("#") or stripped.startswith("!"): continue if "=" in stripped: key, value = stripped.split("=", 1) mapping[key.strip()] = int(value.strip()) return mapping def parse_properties(file_path): props = {} logical = "" with open(file_path, "r", encoding="utf-8") as f: for raw in f: line = raw.rstrip("\n").rstrip("\r") stripped = line.lstrip() if not stripped or stripped.startswith("#") or stripped.startswith("!"): continue if line.rstrip().endswith("\\"): part = line.rstrip()[:-1] logical += part continue else: logical += line if "=" in logical: key, value = logical.split("=", 1) elif ":" in logical: key, value = logical.split(":", 1) else: logical = "" continue # props[key.strip()] = value.strip() props[key.strip()] = value.lstrip().rstrip("\n\r") logical = "" if logical: if "=" in logical: key, value = logical.split("=", 1) props[key.strip()] = value.strip() elif ":" in logical: key, value = logical.split(":", 1) props[key.strip()] = value.strip() return props def extract_allowed_msg_types(props): raw = props.get("msgType.allow", "") raw = raw.replace("\\", "") return [p.strip() for p in raw.split(",") if p.strip()] def group_by_full_prefix(props): result = defaultdict(lambda: {"titles": {}, "bodies": {}}) for key, value in props.items(): parts = key.split(".") if len(parts) < 3: continue full_prefix = ".".join(parts[:-2]) field = parts[-2] lang = parts[-1] if field == "title": result[full_prefix]["titles"][lang] = value elif field == "body": result[full_prefix]["bodies"][lang] = value return result def replace_app_category(appCategory): if appCategory == "deco": return "aria" elif appCategory == "alert": return "common" elif appCategory == "notification": return "vigi" else: return appCategory def set_payload_builder(appCategory, notificationType): if appCategory == "vigi": return ["apnsNotificationBuilder","gcmNotificationBuilder"] elif appCategory == "tether": return ["tetherFcmPayloadBuilder", "tetherAPNsPayloadBuilder"] elif appCategory == "verification": return ["verificationApnsPayloadBuilder", "verificationFcmPayloadBuilder"] elif appCategory == "tapo": # 优先完全匹配 if notificationType in the_merge_map: return the_merge_map[notificationType] # 尝试前缀匹配:仅匹配第一个下划线前的部分 parts = notificationType.split("_", 1) if len(parts) > 1: base_key = parts[0] if base_key in the_merge_map: return the_merge_map[base_key] elif appCategory == "halo": if notificationType in the_halo_merge_map: return the_halo_merge_map[notificationType] parts = notificationType.split("_", 1) if len(parts) > 1: base_key = parts[0] if base_key in the_halo_merge_map: return the_halo_merge_map[base_key] # 默认返回 return ["tapoApnsNotificationBuilder", "tapoFcmNotificationBuilder"] else: return ["apnsNotificationBuilder","gcmNotificationBuilder"] def build_json(notification_type, titles, bodies, base_template, visible_quantity_map, appCategory): obj = dict(base_template) obj["notification_type"] = notification_type if appCategory == "tapo": obj["scenario_list"] = ["PERSISTENCE_NOTIFICATION"] if appCategory == "halo": obj["scenario_list"] = ["PERSISTENCE_NOTIFICATION"] if appCategory == "aria": obj["scenario_list"] = ["PERSISTENCE_NOTIFICATION"] if notification_type in multi_lang_set: obj["config"]["multilingual_vocabularys"] = ["vehicleColor", "vehicleType"] obj["config"] = dict(base_template["config"]) # obj["config"]["ttl"] = TTL_MAPPING.get(notification_type, base_template["config"]["ttl"]) obj["config"]["ttl"] = get_ttl(notification_type, TTL_MAPPING, base_template["config"]["ttl"]) matched_key = None for key in sorted(visible_quantity_map.keys(), key=lambda k: -len(k)): # 按键长降序遍历 if notification_type.startswith(key): matched_key = key break # obj["config"]["visible_quantity"] = visible_quantity_map.get(notification_type, base_template["config"]["visible_quantity"]) obj["config"]["visible_quantity"] = visible_quantity_map.get(matched_key, base_template["config"]["visible_quantity"]) obj["config"]["support_multiLanguage"] = set_support_multiLanguage(appCategory, notification_type) obj["config"]["enable_persistent"] = set_enble_persistent(appCategory, notification_type) obj["config"]["app_payload_builder_list"] = set_payload_builder(appCategory, notification_type) obj["app_category"] = appCategory obj["copywriting_list"] = [ { "locale": lang, "title": titles.get(lang, ""), "body": bodies.get(lang, "") } for lang in sorted(titles.keys() | bodies.keys()) ] return obj def unescape_java_string(s: str) -> str: if not s: return s if "\\u" in s: try: s = codecs.decode(s, 'unicode_escape') except Exception: pass s = s.replace('\\"', '"').replace("\\'", "'") return s def clean_copywritings(grouped): for prefix, vals in grouped.items(): for lang, text in vals["titles"].items(): vals["titles"][lang] = unescape_java_string(text) for lang, text in vals["bodies"].items(): vals["bodies"][lang] = unescape_java_string(text) return grouped if __name__ == "__main__": base_dir = "F:/propertiesOct/mercury/msgcenter" visible_quantity_file = os.path.join(base_dir, "limit/msg_limit_simplified.properties") output_dir = os.path.join(base_dir, "json/notificationRuleMercury") os.makedirs(output_dir, exist_ok=True) # 遍历 solveProperties 下的所有 .properties 文件(排除 limit 目录) for filename in os.listdir(base_dir): if filename.endswith(".properties") and not filename.startswith("msg_limit"): file_path = os.path.join(base_dir, filename) # 自动识别 app_category if filename == "omadaSightAlertMapping.properties": app_category = "omadaGuard" else: # 原逻辑:从文件名提取 app_category match = re.match(r"([a-z]+)", filename) if not match: print(f"文件名无法匹配 app_category: {filename}") continue app_category = match.group(1) app_category = replace_app_category(app_category) # 自动生成输出路径 output_filename = os.path.splitext(filename)[0] + ".json" output_path = os.path.join(output_dir, output_filename) props = parse_properties(file_path) allowed_msg_types = extract_allowed_msg_types(props) grouped = group_by_full_prefix(props) grouped = clean_copywritings(grouped) visible_quantity_map = load_visible_quantity_map(visible_quantity_file) print("**********",output_filename, app_category) results = [ build_json(full_prefix, vals["titles"], vals["bodies"], BASE_TEMPLATE, visible_quantity_map, app_category) for full_prefix, vals in grouped.items() ] with open(output_path, "w", encoding="utf-8") as f: json.dump(results, f, ensure_ascii=False, indent=4) print(f"[OK] {filename} → {output_filename} (app_category={app_category})")修改一下,结合之前查询子消息类型的代码,将子消息类型在构建json的时候补充到"msgSubType": [""]当中,例如tapoDeviceWrongTry保持原有的逻辑,并且将 - tapoDeviceWrongTry_wrongTryType2 - tapoDeviceWrongTry_wrongTryType4 - tapoDeviceWrongTry_wrongTryType3 - tapoDeviceWrongTry_wrongTryType1这四个消息类型加到"msgSubType": [""]当中
最新发布
11-07
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值