github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/internal/json/error.go (about)

     1  // Copyright 2023 CloudWeGo Authors.
     2  // 
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // 
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  // 
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package json
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  
    21  	"github.com/cloudwego/dynamicgo/internal/native/types"
    22  )
    23  
    24  type SyntaxError struct {
    25  	Pos  int
    26  	Src  string
    27  	Code types.ParsingError
    28  	Msg  string
    29  }
    30  
    31  func (self SyntaxError) Error() string {
    32  	return fmt.Sprintf("%q", self.Description())
    33  }
    34  
    35  func (self SyntaxError) Description() string {
    36  	return "Syntax error " + self.Locate()
    37  }
    38  
    39  func (self SyntaxError) Locate() string {
    40  	i := 16
    41  	p := self.Pos - i
    42  	q := self.Pos + i
    43  
    44  	/* check for empty source */
    45  	if self.Src == "" {
    46  		return fmt.Sprintf("no sources available: %#v", self)
    47  	}
    48  
    49  	/* prevent slicing before the beginning */
    50  	if p < 0 {
    51  		p, q, i = 0, q-p, i+p
    52  	}
    53  
    54  	/* prevent slicing beyond the end */
    55  	if n := len(self.Src); q > n {
    56  		n = q - n
    57  		q = len(self.Src)
    58  
    59  		/* move the left bound if possible */
    60  		if p > n {
    61  			i += n
    62  			p -= n
    63  		}
    64  	}
    65  
    66  	/* left and right length */
    67  	x := clamp_zero(i)
    68  	y := clamp_zero(q - p - i - 1)
    69  
    70  	/* compose the error description */
    71  	return fmt.Sprintf(
    72  		"at index %d: %s\n\n\t%s\n\t%s^%s\n",
    73  		self.Pos,
    74  		self.Message(),
    75  		self.Src[p:q],
    76  		strings.Repeat(".", x),
    77  		strings.Repeat(".", y),
    78  	)
    79  }
    80  
    81  func (self SyntaxError) Message() string {
    82  	if self.Msg == "" {
    83  		return self.Code.Message()
    84  	}
    85  	return self.Msg
    86  }
    87  
    88  func clamp_zero(v int) int {
    89  	if v < 0 {
    90  		return 0
    91  	} else {
    92  		return v
    93  	}
    94  }