@@ -43,6 +43,13 @@ impl PartialEq for RelayMap {
4343impl Eq for RelayMap { }
4444
4545impl RelayMap {
46+ /// Creates an empty relay map.
47+ pub fn empty ( ) -> Self {
48+ Self {
49+ relays : Default :: default ( ) ,
50+ }
51+ }
52+
4653 /// Returns the URLs of all servers in this relay map.
4754 ///
4855 /// This function is generic over the container to collect into. If you simply want a list
@@ -59,13 +66,6 @@ impl RelayMap {
5966 . collect :: < T > ( )
6067 }
6168
62- /// Creates an empty relay map.
63- pub fn empty ( ) -> Self {
64- Self {
65- relays : Default :: default ( ) ,
66- }
67- }
68-
6969 /// Returns a list with the [`RelayConfig`] for each relay in this relay map.
7070 ///
7171 /// This function is generic over the container to collect into. If you simply want a list
@@ -111,14 +111,27 @@ impl RelayMap {
111111 pub fn remove ( & self , url : & RelayUrl ) -> Option < Arc < RelayConfig > > {
112112 self . relays . write ( ) . expect ( "poisoned" ) . remove ( url)
113113 }
114+
115+ /// Extends this `RelayMap` with another one.
116+ pub fn extend ( & self , other : & RelayMap ) {
117+ let mut a = self . relays . write ( ) . expect ( "poisoned" ) ;
118+ let b = other. relays . read ( ) . expect ( "poisoned" ) ;
119+ a. extend ( b. iter ( ) . map ( |( a, b) | ( a. clone ( ) , b. clone ( ) ) ) ) ;
120+ }
114121}
115122
116123impl FromIterator < RelayConfig > for RelayMap {
117124 fn from_iter < T : IntoIterator < Item = RelayConfig > > ( iter : T ) -> Self {
125+ Self :: from_iter ( iter. into_iter ( ) . map ( Arc :: new) )
126+ }
127+ }
128+
129+ impl FromIterator < Arc < RelayConfig > > for RelayMap {
130+ fn from_iter < T : IntoIterator < Item = Arc < RelayConfig > > > ( iter : T ) -> Self {
118131 Self {
119132 relays : Arc :: new ( RwLock :: new (
120133 iter. into_iter ( )
121- . map ( |endpoint | ( endpoint . url . clone ( ) , Arc :: new ( endpoint ) ) )
134+ . map ( |config | ( config . url . clone ( ) , config ) )
122135 . collect ( ) ,
123136 ) ) ,
124137 }
@@ -220,3 +233,43 @@ impl fmt::Display for RelayConfig {
220233 write ! ( f, "{}" , self . url)
221234 }
222235}
236+
237+ #[ cfg( test) ]
238+ mod tests {
239+ use std:: str:: FromStr ;
240+
241+ use super :: * ;
242+
243+ #[ test]
244+ fn relay_map_extend ( ) {
245+ let urls1 = vec ! [
246+ RelayUrl :: from_str( "https://hello-a-01.com" ) . unwrap( ) ,
247+ RelayUrl :: from_str( "https://hello-b-01.com" ) . unwrap( ) ,
248+ RelayUrl :: from_str( "https://hello-c-01-.com" ) . unwrap( ) ,
249+ ] ;
250+
251+ let urls2 = vec ! [
252+ RelayUrl :: from_str( "https://hello-a-02.com" ) . unwrap( ) ,
253+ RelayUrl :: from_str( "https://hello-b-02.com" ) . unwrap( ) ,
254+ RelayUrl :: from_str( "https://hello-c-02-.com" ) . unwrap( ) ,
255+ ] ;
256+
257+ let map1 = RelayMap :: from_iter ( urls1. clone ( ) . into_iter ( ) . map ( RelayConfig :: from) ) ;
258+ let map2 = RelayMap :: from_iter ( urls2. clone ( ) . into_iter ( ) . map ( RelayConfig :: from) ) ;
259+
260+ assert_ne ! ( map1, map2) ;
261+
262+ // combine
263+
264+ let map3 = RelayMap :: from_iter (
265+ map1. relays :: < Vec < _ > > ( )
266+ . into_iter ( )
267+ . chain ( map2. relays :: < Vec < _ > > ( ) ) ,
268+ ) ;
269+
270+ assert_eq ! ( map3. len( ) , 6 ) ;
271+
272+ map1. extend ( & map2) ;
273+ assert_eq ! ( map3, map1) ;
274+ }
275+ }
0 commit comments