github.com/viant/toolbox@v0.34.5/text.go (about)

     1  package toolbox
     2  
     3  import (
     4  	"bufio"
     5  	"github.com/viant/toolbox/format"
     6  	"io"
     7  	"unicode"
     8  )
     9  
    10  //IsASCIIText return true if supplied string does not have binary data
    11  func IsASCIIText(candidate string) bool {
    12  	for _, r := range candidate {
    13  		if r == '\n' || r == '\r' || r == '\t' {
    14  			continue
    15  		}
    16  		if r > unicode.MaxASCII || !unicode.IsPrint(r) || r == '`' {
    17  			return false
    18  		}
    19  	}
    20  	return true
    21  }
    22  
    23  //IsPrintText return true if all candidate characters are printable (unicode.IsPrintText)
    24  func IsPrintText(candidate string) bool {
    25  	for _, r := range candidate {
    26  		if !unicode.IsPrint(r) {
    27  			if r == '\n' || r == '\r' || r == '\t' || r == '`' {
    28  				continue
    29  			}
    30  			return false
    31  		}
    32  	}
    33  	return true
    34  }
    35  
    36  //TerminatedSplitN split supplied text into n fragmentCount, each terminated with supplied terminator
    37  func TerminatedSplitN(text string, fragmentCount int, terminator string) []string {
    38  	var result = make([]string, 0)
    39  	if fragmentCount == 0 {
    40  		fragmentCount = 1
    41  	}
    42  	fragmentSize := len(text) / fragmentCount
    43  	lowerBound := 0
    44  	for i := fragmentSize - 1; i < len(text); i++ {
    45  		isLast := i+1 == len(text)
    46  		isAtLeastOfFragmentSize := i-lowerBound >= fragmentSize
    47  		isNewLine := string(text[i:i+len(terminator)]) == terminator
    48  		if (isAtLeastOfFragmentSize && isNewLine) || isLast {
    49  			result = append(result, string(text[lowerBound:i+1]))
    50  			lowerBound = i + 1
    51  		}
    52  	}
    53  	return result
    54  }
    55  
    56  //SplitTextStream divides reader supplied text by number of specified line
    57  func SplitTextStream(reader io.Reader, writerProvider func() io.WriteCloser, elementCount int) error {
    58  	scanner := bufio.NewScanner(reader)
    59  	var writer io.WriteCloser
    60  	counter := 0
    61  	var err error
    62  	if elementCount == 0 {
    63  		elementCount = 1
    64  	}
    65  	for scanner.Scan() {
    66  
    67  		if writer == nil {
    68  			writer = writerProvider()
    69  		}
    70  		data := scanner.Bytes()
    71  		if err = scanner.Err(); err != nil {
    72  			return err
    73  		}
    74  
    75  		if counter > 0 {
    76  			if _, err = writer.Write([]byte{'\n'}); err != nil {
    77  				return err
    78  			}
    79  		}
    80  		if _, err = writer.Write(data); err != nil {
    81  			return err
    82  		}
    83  		counter++
    84  		if counter == elementCount {
    85  			if err := writer.Close(); err != nil {
    86  				return err
    87  			}
    88  			counter = 0
    89  			writer = nil
    90  		}
    91  	}
    92  	if writer != nil {
    93  		return writer.Close()
    94  	}
    95  	return nil
    96  }
    97  
    98  const (
    99  	CaseUpper = iota
   100  	CaseLower
   101  	CaseUpperCamel
   102  	CaseLowerCamel
   103  	CaseUpperUnderscore
   104  	CaseLowerUnderscore
   105  )
   106  
   107  //ToCaseFormat format text,  from, to are const:  CaseLower, CaseUpperCamel,  CaseLowerCamel,  CaseUpperUnderscore,  CaseLowerUnderscore,
   108  // Deprecated: please use format.Case instead
   109  func ToCaseFormat(text string, from, to int) string {
   110  	return format.Case(from).Format(text, format.Case(to))
   111  }