1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #pragma once
8 
9 #include "td/utils/common.h"
10 #include "td/utils/StringBuilder.h"
11 
12 #include <tuple>
13 
14 namespace td {
15 
16 class DcId {
17  public:
18   DcId() = default;
19 
is_valid(int32 dc_id)20   static bool is_valid(int32 dc_id) {
21     return 1 <= dc_id && dc_id <= 1000;
22   }
main()23   static DcId main() {
24     return DcId{MainDc, false};
25   }
invalid()26   static DcId invalid() {
27     return DcId{Invalid, false};
28   }
internal(int32 id)29   static DcId internal(int32 id) {
30     CHECK(is_valid(id));
31     return DcId{id, false};
32   }
external(int32 id)33   static DcId external(int32 id) {
34     CHECK(is_valid(id));
35     return DcId{id, true};
36   }
empty()37   static DcId empty() {
38     return {};
39   }
from_value(int32 value)40   static DcId from_value(int32 value) {
41     return DcId{value, false};
42   }
create(int32 dc_id_value)43   static DcId create(int32 dc_id_value) {
44     if (DcId::is_valid(dc_id_value)) {
45       return DcId(dc_id_value, false);
46     } else {
47       return DcId::invalid();
48     }
49   }
50 
is_empty()51   bool is_empty() const {
52     return !is_valid();
53   }
is_main()54   bool is_main() const {
55     return dc_id_ == MainDc;
56   }
get_raw_id()57   int32 get_raw_id() const {
58     CHECK(is_exact());
59     return dc_id_;
60   }
get_value()61   int32 get_value() const {
62     return dc_id_;
63   }
is_internal()64   bool is_internal() const {
65     return !is_external();
66   }
is_external()67   bool is_external() const {
68     return is_external_;
69   }
is_exact()70   bool is_exact() const {
71     return dc_id_ > 0;
72   }
73   bool operator==(DcId other) const {
74     return dc_id_ == other.dc_id_ && is_external_ == other.is_external_;
75   }
76   bool operator<(DcId other) const {
77     return std::tie(dc_id_, is_external_) < std::tie(other.dc_id_, other.is_external_);
78   }
79   bool operator!=(DcId other) const {
80     return !(*this == other);
81   }
82 
83  private:
84   enum : int32 { Empty = 0, MainDc = -1, Invalid = -2 };
85   int32 dc_id_{Empty};
86   bool is_external_{false};
87 
DcId(int32 dc_id,bool is_external)88   DcId(int32 dc_id, bool is_external) : dc_id_(dc_id), is_external_(is_external) {
89   }
90 
is_valid()91   bool is_valid() const {
92     return is_exact() || is_main();
93   }
94 };
95 
96 inline StringBuilder &operator<<(StringBuilder &sb, const DcId &dc_id) {
97   sb << "DcId{";
98   if (dc_id == DcId::invalid()) {
99     sb << "invalid";
100   } else if (dc_id == DcId()) {
101     sb << "empty";
102   } else if (dc_id.is_empty()) {
103     sb << "is_empty";
104   } else if (dc_id.is_main()) {
105     sb << "main";
106   } else {
107     sb << dc_id.get_raw_id();
108     if (dc_id.is_external()) {
109       sb << " external";
110     }
111   }
112   sb << "}";
113   return sb;
114 }
115 
116 }  // namespace td
117