package rings import ( "net/netip" ) // DecodeAddress extracts ring address fields from a given 10.0.0.0/8 // address. // // revive:disable:function-result-limit func DecodeAddress[T ~uint | NodeID](addr netip.Addr) (RingID, RegionID, ZoneID, T) { // revive:enable:function-result-limit if addr.IsValid() { if addr.Is4In6() { addr = addr.Unmap() } if addr.Is4() { a4 := addr.As4() return unsafeDecodeAddress[T](a4[0], a4[1], a4[2], a4[3]) } } return UnspecifiedRingID, 0, 0, 0 } // revive:disable:function-result-limit func unsafeDecodeAddress[T ~uint | NodeID](a, b, c, d byte) (RingID, RegionID, ZoneID, T) { // revive:enable:function-result-limit switch { case a != 10: return UnspecifiedRingID, 0, 0, 0 case b == 0x00: // 10.00.RZ.dd k := RingZeroID r := RegionID(c >> 4) z := ZoneID(c & 0xf) n := T(d) return k, r, z, n case b&0xf0 != 0: // 10.Rb.cc.dd k := RingThreeID r := RegionID(b >> 4) n2 := T(b & 0x0f) n1 := T(c) n0 := T(d) n := n0 + n1<<8 + n2<<16 return k, r, 0, n case c&0xf0 != 0: // 10.0R.Zc.dd k := RingOneID r := RegionID(b) z := ZoneID(c >> 4) n1 := T(c & 0x0f) n0 := T(d) n := n0 + n1<<8 return k, r, z, n default: // 10.0R.0c.dd k := RingTwoID r := RegionID(b) n1 := T(c & 0x0f) n0 := T(d) n := n0 + n1<<8 return k, r, 0, n } }