@@ -190,6 +190,8 @@ pub enum CompletionError {
190190 MissingSelfRecipient ,
191191 /// {0:?} and {1:?} have the same phone number
192192 DuplicateContactE164 ( RecipientId , RecipientId ) ,
193+ /// {0:?} and {1:?} have the same username
194+ DuplicateContactUsername ( RecipientId , RecipientId ) ,
193195 /// {0:?} and {1:?} have the same ACI
194196 DuplicateContactAci ( RecipientId , RecipientId ) ,
195197 /// {0:?} and {1:?} have the same PNI
@@ -321,18 +323,23 @@ impl<M: Method + ReferencedTypes> CompletedBackup<M> {
321323 * std:: mem:: size_of:: <( Aci , RecipientId ) >( )
322324 + HIGH_BUT_REASONABLE_NUMBER_OF_CONTACTS
323325 * std:: mem:: size_of:: <( Pni , RecipientId ) >( )
326+ + HIGH_BUT_REASONABLE_NUMBER_OF_CONTACTS
327+ * std:: mem:: size_of:: <( & str , RecipientId ) >( )
324328 + HIGH_BUT_REASONABLE_NUMBER_OF_GROUPS
325329 * std:: mem:: size_of:: <( zkgroup:: GroupMasterKeyBytes , RecipientId ) >( )
326330 + HIGH_BUT_REASONABLE_NUMBER_OF_DISTRIBUTION_LISTS
327331 * std:: mem:: size_of:: <( uuid:: Uuid , RecipientId ) >( )
328332 + HIGH_BUT_REASONABLE_NUMBER_OF_CALL_LINKS
329333 * std:: mem:: size_of:: <( call:: CallLinkRootKey , RecipientId ) >( )
330- < 250_000 ,
334+ < 350_000 ,
331335 ) ;
332336
333337 let mut e164s = IntMap :: < u64 , RecipientId > :: with_capacity (
334338 recipients. len ( ) . min ( HIGH_BUT_REASONABLE_NUMBER_OF_CONTACTS ) ,
335339 ) ;
340+ let mut usernames = HashMap :: < & str , RecipientId > :: with_capacity (
341+ recipients. len ( ) . min ( HIGH_BUT_REASONABLE_NUMBER_OF_CONTACTS ) ,
342+ ) ;
336343 let mut acis = AssumedRandomInputHasher :: map_with_capacity :: < Aci , RecipientId > (
337344 recipients. len ( ) . min ( HIGH_BUT_REASONABLE_NUMBER_OF_CONTACTS ) ,
338345 ) ;
@@ -365,7 +372,19 @@ impl<M: Method + ReferencedTypes> CompletedBackup<M> {
365372
366373 for ( id, recipient) in recipients. iter ( ) {
367374 match recipient. as_ref ( ) {
368- MinimalRecipientData :: Contact { e164, aci, pni } => {
375+ MinimalRecipientData :: Contact {
376+ e164,
377+ aci,
378+ pni,
379+ username,
380+ } => {
381+ insert_or_error (
382+ & mut usernames,
383+ username. as_deref ( ) ,
384+ id,
385+ CompletionError :: DuplicateContactUsername ,
386+ ) ?;
387+
369388 // We can't use insert_or_throw_error for `e164s` because it's an IntMap.
370389 // Here's an inlined copy:
371390 if let Some ( e164) = * e164 {
@@ -1279,6 +1298,9 @@ mod test {
12791298 ( CompletionError :: DuplicateContactE164 , |x| {
12801299 x. e164 = Some ( proto:: Contact :: TEST_E164 . into( ) ) ;
12811300 } ) ,
1301+ ( CompletionError :: DuplicateContactUsername , |x| {
1302+ x. username = Some ( "duplicate.1234" . to_owned( ) ) ;
1303+ } ) ,
12821304 ]
12831305 ) ]
12841306 fn duplicate_contact_id < M : Method + ReferencedTypes > (
0 commit comments