pub fn add_tag<A: ToString, B: ToString>(&mut self, tag_name: A, attr_names: B) -> bool {
        let tag = tag_name.to_string().trim().to_lowercase().to_string();

        if tag.len() == 0 
            || tag.len() > 32 
            || self.added_tags.contains_key(&tag) {
            return false
        }

        if self.added_tags.len() >= 255 {
            return false
        }

        // ID should not be zero as it is an indicator of no match
        let id = self.added_tags.len() + 1;
        let id_i16 = id as i16;

        self.added_tags.insert(tag.clone(), id_i16);

        // remember tag string: it will be returned in case of matching
        self.strings[id] = Some(tag.clone());

        // add both lower...
        if !self.add_tag_internal(tag.clone(), id, id*2+0) {
            return false
        }
           
        // ...and upper case tag values
        if !self.add_tag_internal(tag.to_uppercase(), id, id*2+1) {
            return false
        }

        // allocate memory for attribute hashes for this tag
        self.attr_data[id] = vec![0; 256];

        // now add attribute names
        let lowered_attr_names = attr_names.to_string().to_lowercase();
        let names = lowered_attr_names.split(",");

        for name in names {
            let att_name = name.trim().to_string();

            if att_name.len() == 0 {
                continue
            }

            // only add attribute if we have not got it added 
            // for same first char of the same tag:
            let first_ch = att_name.chars().nth(0).unwrap();

            if self.attr_data[id][first_ch as usize] > 0
                || self.attr_data[id][first_ch.to_uppercase().next().unwrap() as usize] > 0 {
                continue
            }

            let attr_id = if self.added_attributes.contains_key(&att_name) {
                self.added_attributes[&att_name]
            } else {
                let new_id = self.added_attributes.len() + 1;
                self.added_attributes.insert(att_name.clone(), new_id as i16);
                self.attrs[new_id] = Some(att_name.clone());

                new_id as i16
            };

            // add both lower...
            self.add_attribute(att_name.clone(), id_i16, attr_id*2 + 0);

            // ... and upper case tag values
            self.add_attribute(att_name.to_uppercase(), id_i16, attr_id*2 + 1);
        }

        true
    }
/// Adds tag to list of tracked tags (don't add too many, if you have got multiple same first
/// 2 chars then duplicates won't be added, so make sure the first added tags are the MOST LIKELY to be found)
Adds tag to list of tracked tags (don't add too many, if you have got multiple same first
2 chars then duplicates won't be added, so make sure the first added tags are the MOST LIKELY to be found)
Adds tag to list of tracked tags ( don ' t add too many if you have got multiple same first 2 chars then duplicates won ' t be added so make sure the first added tags are the MOST LIKELY to be found )
pub fn add_tag<A: ToString, B: ToString>(&mut self, tag_name: A, attr_names: B) -> bool {
        let tag = tag_name.to_string().trim().to_lowercase().to_string();
        if tag.len() == 0 
            || tag.len() > 32 
            || self.added_tags.contains_key(&tag) {
            return false
        }
        if self.added_tags.len() >= 255 {
            return false
        }
        // ID should not be zero as it is an indicator of no match
        let id = self.added_tags.len() + 1;
        let id_i16 = id as i16;
        self.added_tags.insert(tag.clone(), id_i16);
        // remember tag string: it will be returned in case of matching
        self.strings[id] = Some(tag.clone());
        // add both lower...
        if !self.add_tag_internal(tag.clone(), id, id*2+0) {
            return false
        }
        // ...and upper case tag values
        if !self.add_tag_internal(tag.to_uppercase(), id, id*2+1) {
            return false
        }
        // allocate memory for attribute hashes for this tag
        self.attr_data[id] = vec![0; 256];
        // now add attribute names
        let lowered_attr_names = attr_names.to_string().to_lowercase();
        let names = lowered_attr_names.split(",");
        for name in names {
            let att_name = name.trim().to_string();
            if att_name.len() == 0 {
                continue
            }
            // only add attribute if we have not got it added 
            // for same first char of the same tag:
            let first_ch = att_name.chars().nth(0).unwrap();
            if self.attr_data[id][first_ch as usize] > 0
                || self.attr_data[id][first_ch.to_uppercase().next().unwrap() as usize] > 0 {
                continue
            }
            let attr_id = if self.added_attributes.contains_key(&att_name) {
                self.added_attributes[&att_name]
            } else {
                let new_id = self.added_attributes.len() + 1;
                self.added_attributes.insert(att_name.clone(), new_id as i16);
                self.attrs[new_id] = Some(att_name.clone());
                new_id as i16
            };
            // add both lower...
            self.add_attribute(att_name.clone(), id_i16, attr_id*2 + 0);
            // ... and upper case tag values
            self.add_attribute(att_name.to_uppercase(), id_i16, attr_id*2 + 1);
        }
        true
    }
pub fn add_tag < A : ToString , B : ToString > ( & mut self , tag_name : A , attr_names : B ) -> bool { let tag = tag_name . to_string ( ) . trim ( ) . to_lowercase ( ) . to_string ( ) ; if tag . len ( ) == 0 || tag . len ( ) > 32 || self . added_tags . contains_key ( & tag ) { return false } if self . added_tags . len ( ) >= 255 { return false } // ID should not be zero as it is an indicator of no match let id = self . added_tags . len ( ) + 1 ; let id_i16 = id as i16 ; self . added_tags . insert ( tag . clone ( ) , id_i16 ) ; // remember tag string: it will be returned in case of matching self . strings [ id ] = Some ( tag . clone ( ) ) ; // add both lower... if ! self . add_tag_internal ( tag . clone ( ) , id , id * 2 + 0 ) { return false } // ...and upper case tag values if ! self . add_tag_internal ( tag . to_uppercase ( ) , id , id * 2 + 1 ) { return false } // allocate memory for attribute hashes for this tag self . attr_data [ id ] = vec ! [ 0 256 ] ; // now add attribute names let lowered_attr_names = attr_names . to_string ( ) . to_lowercase ( ) ; let names = lowered_attr_names . split ( " " ) ; for name in names { let att_name = name . trim ( ) . to_string ( ) ; if att_name . len ( ) == 0 { continue } // only add attribute if we have not got it added  // for same first char of the same tag: let first_ch = att_name . chars ( ) . nth ( 0 ) . unwrap ( ) ; if self . attr_data [ id ] [ first_ch as usize ] > 0 || self . attr_data [ id ] [ first_ch . to_uppercase ( ) . next ( ) . unwrap ( ) as usize ] > 0 { continue } let attr_id = if self . added_attributes . contains_key ( & att_name ) { self . added_attributes [ & att_name ] } else { let new_id = self . added_attributes . len ( ) + 1 ; self . added_attributes . insert ( att_name . clone ( ) , new_id as i16 ) ; self . attrs [ new_id ] = Some ( att_name . clone ( ) ) ; new_id as i16 } ; // add both lower... self . add_attribute ( att_name . clone ( ) , id_i16 , attr_id * 2 + 0 ) ; // ... and upper case tag values self . add_attribute ( att_name . to_uppercase ( ) , id_i16 , attr_id * 2 + 1 ) ; } true }
Adds tag to list of tracked tags (don't add too many, if you have got multiple same first
2 chars then duplicates won't be added, so make sure the first added tags are the MOST LIKELY to be found)
Adds tag to list of tracked tags ( don ' t add too many if you have got multiple same first 2 chars then duplicates won ' t be added so make sure the first added tags are the MOST LIKELY to be found )
&mut self
tag_name
A
attr_names
B
&mut self
tag_name
A
attr_names
B