github.com/la5nta/wl2k-go@v0.11.8/transport/dial.go (about)

     1  // Copyright 2016 Martin Hebnes Pedersen (LA5NTA). All rights reserved.
     2  // Use of this source code is governed by the MIT-license that can be
     3  // found in the LICENSE file.
     4  
     5  package transport
     6  
     7  import (
     8  	"context"
     9  	"errors"
    10  	"net"
    11  	"sync"
    12  )
    13  
    14  var (
    15  	ErrInvalidTarget     = errors.New("Invalid or missing target callsign")
    16  	ErrDigisUnsupported  = errors.New("Digipeater path is not supported by this scheme")
    17  	ErrMissingDialer     = errors.New("No dialer has been registered for this scheme")
    18  	ErrUnsupportedScheme = errors.New("Unsupported URL scheme")
    19  )
    20  
    21  // noCtxDialer wraps a Dialer to implement the ContextDialer interface.
    22  type noCtxDialer struct{ Dialer }
    23  
    24  func (d noCtxDialer) DialURLContext(_ context.Context, url *URL) (net.Conn, error) {
    25  	return d.DialURL(url)
    26  }
    27  
    28  // DialURL calls the url.Scheme's Dialer.
    29  //
    30  // If the URL's scheme is not registered, ErrMissingDialer is returned.
    31  func DialURL(url *URL) (net.Conn, error) {
    32  	return DialURLContext(context.Background(), url)
    33  }
    34  
    35  // DialURLContext calls the url.Scheme's ContextDialer.
    36  //
    37  // If the URL's scheme is not registered, ErrMissingDialer is returned.
    38  func DialURLContext(ctx context.Context, url *URL) (net.Conn, error) {
    39  	dialers.mu.Lock()
    40  	dialer, ok := dialers.m[url.Scheme]
    41  	dialers.mu.Unlock()
    42  	if !ok {
    43  		return nil, ErrMissingDialer
    44  	}
    45  	return dialer.DialURLContext(ctx, url)
    46  }
    47  
    48  var dialers struct {
    49  	mu sync.Mutex
    50  	m  map[string]ContextDialer
    51  }
    52  
    53  // RegisterContextDialer registers a new scheme and it's ContextDialer.
    54  //
    55  // The list of registered dialers is used by DialURL and DialURLContext.
    56  func RegisterContextDialer(scheme string, dialer ContextDialer) {
    57  	dialers.mu.Lock()
    58  
    59  	if dialers.m == nil {
    60  		dialers.m = make(map[string]ContextDialer)
    61  	}
    62  
    63  	dialers.m[scheme] = dialer
    64  
    65  	dialers.mu.Unlock()
    66  }
    67  
    68  // RigisterDialer registers a new scheme and it's Dialer.
    69  //
    70  // The list of registered dialers is used by DialURL and DialURLContext.
    71  func RegisterDialer(scheme string, dialer Dialer) {
    72  	d, ok := dialer.(ContextDialer)
    73  	if !ok {
    74  		d = noCtxDialer{dialer}
    75  	}
    76  	RegisterContextDialer(scheme, d)
    77  }
    78  
    79  // UnregisterDialer removes the given scheme's dialer from the list of dialers.
    80  func UnregisterDialer(scheme string) {
    81  	dialers.mu.Lock()
    82  	delete(dialers.m, scheme)
    83  	dialers.mu.Unlock()
    84  }