@@ -370,6 +370,51 @@ impl Team {
370370 Ok ( lists)
371371 }
372372
373+ /// `on_exclude_not_included` is a function that is returned when an excluded member
374+ /// wasn't included.
375+ fn expand_zulip_membership (
376+ & self ,
377+ data : & Data ,
378+ common : & RawZulipCommon ,
379+ on_exclude_not_included : impl Fn ( & str ) -> Error ,
380+ ) -> Result < Vec < ZulipMember > , Error > {
381+ let mut members = if common. include_team_members {
382+ self . members ( data) ?
383+ } else {
384+ HashSet :: new ( )
385+ } ;
386+ for person in & common. extra_people {
387+ members. insert ( person. as_str ( ) ) ;
388+ }
389+ for team in & common. extra_teams {
390+ let team = data
391+ . team ( team)
392+ . ok_or_else ( || format_err ! ( "team {} is missing" , team) ) ?;
393+ members. extend ( team. members ( data) ?) ;
394+ }
395+ for excluded in & common. excluded_people {
396+ if !members. remove ( excluded. as_str ( ) ) {
397+ return Err ( on_exclude_not_included ( excluded) ) ;
398+ }
399+ }
400+
401+ let mut final_members = Vec :: new ( ) ;
402+ for member in members. iter ( ) {
403+ let member = data
404+ . person ( member)
405+ . ok_or_else ( || format_err ! ( "{} does not have a person configuration" , member) ) ?;
406+ let member = match ( member. github . clone ( ) , member. zulip_id ) {
407+ ( github, Some ( zulip_id) ) => ZulipMember :: MemberWithId { github, zulip_id } ,
408+ ( github, _) => ZulipMember :: MemberWithoutId { github } ,
409+ } ;
410+ final_members. push ( member) ;
411+ }
412+ for & extra in & common. extra_zulip_ids {
413+ final_members. push ( ZulipMember :: JustId ( extra) ) ;
414+ }
415+ Ok ( final_members)
416+ }
417+
373418 pub ( crate ) fn raw_zulip_groups ( & self ) -> & [ RawZulipGroup ] {
374419 & self . zulip_groups
375420 }
@@ -379,46 +424,17 @@ impl Team {
379424 let zulip_groups = & self . zulip_groups ;
380425
381426 for raw_group in zulip_groups {
382- let mut group = ZulipGroup {
383- name : raw_group. name . clone ( ) ,
384- includes_team_members : raw_group. include_team_members ,
385- members : Vec :: new ( ) ,
386- } ;
387-
388- let mut members = if raw_group. include_team_members {
389- self . members ( data) ?
390- } else {
391- HashSet :: new ( )
392- } ;
393- for person in & raw_group. extra_people {
394- members. insert ( person. as_str ( ) ) ;
395- }
396- for team in & raw_group. extra_teams {
397- let team = data
398- . team ( team)
399- . ok_or_else ( || format_err ! ( "team {} is missing" , team) ) ?;
400- members. extend ( team. members ( data) ?) ;
401- }
402- for excluded in & raw_group. excluded_people {
403- if !members. remove ( excluded. as_str ( ) ) {
404- bail ! ( "'{excluded}' was specifically excluded from the Zulip group '{}' but they were already not included" , raw_group. name) ;
405- }
406- }
407-
408- for member in members. iter ( ) {
409- let member = data. person ( member) . ok_or_else ( || {
410- format_err ! ( "{} does not have a person configuration" , member)
411- } ) ?;
412- let member = match ( member. github . clone ( ) , member. zulip_id ) {
413- ( github, Some ( zulip_id) ) => ZulipGroupMember :: MemberWithId { github, zulip_id } ,
414- ( github, _) => ZulipGroupMember :: MemberWithoutId { github } ,
415- } ;
416- group. members . push ( member) ;
417- }
418- for & extra in & raw_group. extra_zulip_ids {
419- group. members . push ( ZulipGroupMember :: JustId ( extra) ) ;
420- }
421- groups. push ( group) ;
427+ groups. push ( ZulipGroup ( ZulipCommon {
428+ name : raw_group. common . name . clone ( ) ,
429+ includes_team_members : raw_group. common . include_team_members ,
430+ members : self . expand_zulip_membership (
431+ data,
432+ & raw_group. common ,
433+ |excluded| {
434+ format_err ! ( "'{excluded}' was specifically excluded from the Zulip group '{}' but they were already not included" , raw_group. common. name)
435+ } ,
436+ ) ?,
437+ } ) ) ;
422438 }
423439 Ok ( groups)
424440 }
@@ -432,47 +448,17 @@ impl Team {
432448 let zulip_streams = self . raw_zulip_streams ( ) ;
433449
434450 for raw_stream in zulip_streams {
435- let mut stream = ZulipStream {
436- name : raw_stream. name . clone ( ) ,
437- members : Vec :: new ( ) ,
438- } ;
439-
440- let mut members = if raw_stream. include_team_members {
441- self . members ( data) ?
442- } else {
443- HashSet :: new ( )
444- } ;
445- for person in & raw_stream. extra_people {
446- members. insert ( person. as_str ( ) ) ;
447- }
448- for team in & raw_stream. extra_teams {
449- let team = data
450- . team ( team)
451- . ok_or_else ( || format_err ! ( "team {} is missing" , team) ) ?;
452- members. extend ( team. members ( data) ?) ;
453- }
454- for excluded in & raw_stream. excluded_people {
455- if !members. remove ( excluded. as_str ( ) ) {
456- bail ! ( "'{excluded}' was specifically excluded from the Zulip stream '{}' but they were already not included" , raw_stream. name) ;
457- }
458- }
459-
460- for member in members. iter ( ) {
461- let member = data. person ( member) . ok_or_else ( || {
462- format_err ! ( "{} does not have a person configuration" , member)
463- } ) ?;
464- let member = match ( member. github . clone ( ) , member. zulip_id ) {
465- ( github, Some ( zulip_id) ) => {
466- ZulipStreamMember :: MemberWithId { github, zulip_id }
467- }
468- ( github, _) => ZulipStreamMember :: MemberWithoutId { github } ,
469- } ;
470- stream. members . push ( member) ;
471- }
472- for & extra in & raw_stream. extra_zulip_ids {
473- stream. members . push ( ZulipStreamMember :: JustId ( extra) ) ;
474- }
475- streams. push ( stream) ;
451+ streams. push ( ZulipStream ( ZulipCommon {
452+ name : raw_stream. common . name . clone ( ) ,
453+ includes_team_members : raw_stream. common . include_team_members ,
454+ members : self . expand_zulip_membership (
455+ data,
456+ & raw_stream. common ,
457+ |excluded| {
458+ format_err ! ( "'{excluded}' was specifically excluded from the Zulip stream '{}' but they were already not included" , raw_stream. common. name)
459+ } ,
460+ ) ?,
461+ } ) ) ;
476462 }
477463 Ok ( streams)
478464 }
@@ -733,7 +719,7 @@ pub(crate) struct TeamList {
733719
734720#[ derive( serde_derive:: Deserialize , Debug ) ]
735721#[ serde( rename_all = "kebab-case" , deny_unknown_fields) ]
736- pub ( crate ) struct RawZulipGroup {
722+ pub ( crate ) struct RawZulipCommon {
737723 pub ( crate ) name : String ,
738724 #[ serde( default = "default_true" ) ]
739725 pub ( crate ) include_team_members : bool ,
@@ -747,20 +733,18 @@ pub(crate) struct RawZulipGroup {
747733 pub ( crate ) excluded_people : Vec < String > ,
748734}
749735
736+ #[ derive( serde_derive:: Deserialize , Debug ) ]
737+ #[ serde( rename_all = "kebab-case" , deny_unknown_fields) ]
738+ pub ( crate ) struct RawZulipGroup {
739+ #[ serde( flatten) ]
740+ pub ( crate ) common : RawZulipCommon ,
741+ }
742+
750743#[ derive( serde_derive:: Deserialize , Debug ) ]
751744#[ serde( rename_all = "kebab-case" , deny_unknown_fields) ]
752745pub ( crate ) struct RawZulipStream {
753- pub ( crate ) name : String ,
754- #[ serde( default = "default_true" ) ]
755- pub ( crate ) include_team_members : bool ,
756- #[ serde( default ) ]
757- pub ( crate ) extra_people : Vec < String > ,
758- #[ serde( default ) ]
759- pub ( crate ) extra_zulip_ids : Vec < u64 > ,
760- #[ serde( default ) ]
761- pub ( crate ) extra_teams : Vec < String > ,
762- #[ serde( default ) ]
763- pub ( crate ) excluded_people : Vec < String > ,
746+ #[ serde( flatten) ]
747+ pub ( crate ) common : RawZulipCommon ,
764748}
765749
766750#[ derive( Debug ) ]
@@ -780,52 +764,49 @@ impl List {
780764}
781765
782766#[ derive( Debug ) ]
783- pub ( crate ) struct ZulipGroup {
767+ pub ( crate ) struct ZulipCommon {
784768 name : String ,
785769 includes_team_members : bool ,
786- members : Vec < ZulipGroupMember > ,
770+ members : Vec < ZulipMember > ,
787771}
788772
789- impl ZulipGroup {
773+ impl ZulipCommon {
790774 pub ( crate ) fn name ( & self ) -> & str {
791775 & self . name
792776 }
793777
794- /// Whether the group includes the members of the team its associated
778+ /// Whether the group/stream includes the members of the associated team?
795779 pub ( crate ) fn includes_team_members ( & self ) -> bool {
796780 self . includes_team_members
797781 }
798782
799- pub ( crate ) fn members ( & self ) -> & [ ZulipGroupMember ] {
783+ pub ( crate ) fn members ( & self ) -> & [ ZulipMember ] {
800784 & self . members
801785 }
802786}
803787
804- #[ derive( Debug , Clone , Ord , PartialOrd , Eq , PartialEq , Hash ) ]
805- pub ( crate ) enum ZulipGroupMember {
806- MemberWithId { github : String , zulip_id : u64 } ,
807- JustId ( u64 ) ,
808- MemberWithoutId { github : String } ,
809- }
810-
811788#[ derive( Debug ) ]
812- pub ( crate ) struct ZulipStream {
813- name : String ,
814- members : Vec < ZulipStreamMember > ,
815- }
789+ pub ( crate ) struct ZulipGroup ( ZulipCommon ) ;
816790
817- impl ZulipStream {
818- pub ( crate ) fn name ( & self ) -> & str {
819- & self . name
791+ impl std:: ops:: Deref for ZulipGroup {
792+ type Target = ZulipCommon ;
793+ fn deref ( & self ) -> & Self :: Target {
794+ & self . 0
820795 }
796+ }
821797
822- pub ( crate ) fn members ( & self ) -> & [ ZulipStreamMember ] {
823- & self . members
798+ #[ derive( Debug ) ]
799+ pub ( crate ) struct ZulipStream ( ZulipCommon ) ;
800+
801+ impl std:: ops:: Deref for ZulipStream {
802+ type Target = ZulipCommon ;
803+ fn deref ( & self ) -> & Self :: Target {
804+ & self . 0
824805 }
825806}
826807
827808#[ derive( Debug , Clone , Ord , PartialOrd , Eq , PartialEq , Hash ) ]
828- pub ( crate ) enum ZulipStreamMember {
809+ pub ( crate ) enum ZulipMember {
829810 MemberWithId { github : String , zulip_id : u64 } ,
830811 JustId ( u64 ) ,
831812 MemberWithoutId { github : String } ,
0 commit comments