// Copyright 2021 Molecula Corp. All rights reserved. package pgtest import ( "errors" "net" "sync" ) // errListenerClosed is an error returned when the listener is closed. var errListenerClosed = errors.New("listener closed") type inMemoryListener struct { ch chan net.Conn closed chan struct{} once sync.Once } func (l *inMemoryListener) Accept() (net.Conn, error) { select { case <-l.closed: return nil, errListenerClosed default: } select { case conn := <-l.ch: return conn, nil case <-l.closed: return nil, errListenerClosed } } func (l *inMemoryListener) Close() error { l.once.Do(func() { close(l.closed) }) return nil } type memAddr struct{} func (a memAddr) Network() string { return "memory" } func (a memAddr) String() string { return "memory" } func (l *inMemoryListener) Addr() net.Addr { return memAddr{} } func (l *inMemoryListener) Dial() (net.Conn, error) { serverConn, clientConn := net.Pipe() select { case l.ch <- serverConn: return clientConn, nil case <-l.closed: serverConn.Close() clientConn.Close() return nil, errListenerClosed } }