github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/upstream.go (about) 1 package common 2 3 import "net" 4 5 type WithUpstream interface { 6 Upstream() any 7 } 8 9 type stdWithUpstreamNetConn interface { 10 NetConn() net.Conn 11 } 12 13 func Cast[T any](obj any) (T, bool) { 14 if c, ok := obj.(T); ok { 15 return c, true 16 } 17 if u, ok := obj.(WithUpstream); ok { 18 return Cast[T](u.Upstream()) 19 } 20 if u, ok := obj.(stdWithUpstreamNetConn); ok { 21 return Cast[T](u.NetConn()) 22 } 23 return DefaultValue[T](), false 24 } 25 26 func MustCast[T any](obj any) T { 27 value, ok := Cast[T](obj) 28 if !ok { 29 // make panic 30 return obj.(T) 31 } 32 return value 33 } 34 35 func Top(obj any) any { 36 if u, ok := obj.(WithUpstream); ok { 37 return Top(u.Upstream()) 38 } 39 if u, ok := obj.(stdWithUpstreamNetConn); ok { 40 return Top(u.NetConn()) 41 } 42 return obj 43 }