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  }